PHP cannot read cookies from Chrome in certain cases - php

This issue appeared today and it seems to have something to do with webkit.
On pages that redirect via location [301/302] HTTP headers (404 error pages in this case) PHP cannot read the cookies - meaning the $_COOKIE is an empty array.
I'm aware of the webkit bug that using Set-Cookie and Location header in the same response breaks, but this is about reading not writing so it's supposed to be in the request headers.
I'm using the latest Chrome v26. On the backend I have PHP 5.3.10-1ubuntu3.6 on my home server, and the exact same on a production server (which i did not set up and it's not on default settings). On the production server I cannot read the cookies as I said before but on my home/dev server I can.
And it gets worse: On another server which runs PHP 5.3.3-7+squeeze14 I also can't read the cookies if the Content-Type header is not html, but text/plain.
I set the cookies the following way:
if (setcookie($name, $value, $expire, $path, null, isset($_SERVER['HTTPS']), $httponly))
{
$_COOKIE[$name] = $value;
return true;
}
return false;
$httponly is false
$path is '/'
the name consists of lowercase letters
the value consists of numbers and dashes
I can see the cookie in the Developer Tools / Resources tab and it works fine on simple html pages.
I appreciate any help.
Thanks.

the redirect page and the redirector page are at the same domain? Maybe this can being considered as a XSS attempt to stealing cookies. Try to send "Access-Control-Allow-Origin: *" header:
header("Access-Control-Allow-Origin: *" );

In my case, the problem was with session_set_cookie_params(), the parameter for the domain (the 3rd argument) was prefixed with a period ., such as ".localhost". When I removed the ., $_COOKIE variable was populated.

Related

Can cookies created by one php web page can be deleted by another php webpage?

I have created one php web page which creates a cookie. That web page redirects the user on another (second) php web page. On this second web page I'm trying to delete the cookie which is created by the first page. But cookie is not getting deleted. And the second web page shows an error like "can not modify header information"
My php code format for deleting that cookie is like:
if(isset($_COOKIE['cookieName']))
{
setCookie('cookieName','values',time()-3600,'/','example#domain.com',0);
}
I hope you are making use of unset()
Do like this
if(isset($_COOKIE['cookieName']))
{
unset($_COOKIE['cookieName']));
}
Can you try this,
unset($_COOKIE['cookieName']);
setcookie('cookieName', null, -1, '/');
Path:
The path on the server in which the cookie will be available on. If set to '/', the cookie will be available within the entire domain. If set to '/foo/', the cookie will only be available within the /foo/ directory and all sub-directories such as /foo/bar/ of domain. The default value is the current directory that the cookie is being set in.
Domain:
The domain that the cookie is available to. Setting the domain to 'www.example.com' will make the cookie available in the www subdomain and higher subdomains. Cookies available to a lower domain, such as 'example.com' will be available to higher subdomains, such as 'www.example.com'.
Setting cookies is done in the HTTP header. This header is sent before the actual content of the page. As a result, you can only (un)set the cookie of you have not yet sent any output.
This is also stated in the setcookie documentation:
Like other headers, cookies must be sent before any output from your
script (this is a protocol restriction). This requires that you place
calls to this function prior to any output, including and
tags as well as any whitespace.
For example:
<?php
if (isset($_COOKIE['cookieName'])) {
unset($_COOKIE['cookieName']);
setcookie("cookieName", "", time()-3600);
}
?>
<html>
....
</html>
(Also see the question Remove a cookie.)

Unable to setcookie in any browser

So I have done a lot of reading on setting cookies and still cannot find what I am doing wrong here. I started with an if statement to include another script but it soon became clear the cookie wasn't setting so I simplified it and made it just to echo so I could see if it was setting. Its not. I am including it above the <html>.
I am setting the cookie and then refreshing and no matter how many times I refresh it is still returning a NULL result in the echo command.
The setcookie is above all of my html, cookies can't be set after any output??
The value is set, and domain.
All browsers have cookies enabled, and friends have tested this for me so its not local.
Its not the server, I asked my host.
I have even copy/pasted code from PHP manual to no avail.
And of course checked SO a few mil times.
$var='Something';
setcookie ("Name", "$var", time()+3600, '/', 'website.com');
echo $_COOKIE["Name"];
var_dump($_COOKIE["Name"]);
var_dump ($HTTP_COOKIE_VARS);
echo returning NULL and var_dump returning Array(0)
I am going mad, is there something wrong in my code, what am I missing?
The most frequent problem with setting cookies (or any other header) is, that it has to be set before you send first output character. There may be an invisible character before your script (like BOM or whitespace). If you use includes, thare may be a whitespace after the closing tag of your included script.
To debug cookies, one have to debug HTTP headers.
So, get yourself a Firebug, switch to Net tab and watch request and response headers, if you can see any cookie sent by server or returned by browser.
If there will be no trace of cookies - there is some error on the server side then. You need to enable error reporting and displaying in order to see them
ini_set('display_errors',1);
error_reporting(E_ALL);
is a quick and dirty way

Overwrite cookie failed PHP & ASP cross subdomain

I have problem in overwriting cookies value cross sub domains, a website running in ASP which is in www.domain.com and mobile site running in PHP with m.domain.com sharing same cookie
Cookie created in www.domain.com via asp as follow:
Response.Cookies("cookie_name")="value1"
Response.Cookies("cookie_name").Expires=DateAdd("m", 1, Date())
Response.Cookies("cookie_name").Domain = ".domain.com"
Response.Cookies("cookie_name").Path = "/"
Response.Cookies("cookie_name").Secure = false
When i tried to overwrite the value in PHP (m.domain.com) as follow:
setcookie("cookie_name",'value2',time()+60*60*24*30, "/", ".domain.com",false);
the execution return true but when i check the cookie the value wasnt change still "value1"
also had tried to set via header
header("Set-Cookie: cookie_name=value2; path=/; domain=.domain.com; expires=".gmstrftime("%A, %d-%b-%Y %H:%M:%S GMT",time()+60*60*24*30));
but still no efects, any ideas? big thanks.
Finally i made it work
header("Set-Cookie: cookie_name=value2; expires=".gmstrftime("%A, %d-%b-%Y %H:%M:%S GMT",time()+60*60*24*30)."; path=/; domain=domain.com");
Note the domain part (no dot), hope this helps others
PHP and JavaScript sometimes can't work together aswell so I recognise the problem.
I don't know how much you depend on Javascript, but you could use it to set the cookie values(echo-ing "document.cookie = "=;expires=;path="; ").
It's dirty but at least there will be one common divider to worry about; not two.....

Semantics of setting cookies and redirecting without getting header error

I would like to do the following in php :
setcookie('name', $value, $Cookie_Expiration,'/');
then some action
header("location:http://www.example.com")
the problem is that I get :
warning: Cannot modify header information - headers already sent by (...etc )
could you please let me know what i am doing wrong and if there is a way to do this?
by the way , this code is before any output is made ...the cookie setting part works fine on its own and so does the redirection code....the combination fails
thank you
Cookies are sent in the header, and you can't set headers if any output is already sent to the browser (which is is when you set the cookie).
The easiest solution, mind you it is a bit sloppy is to use ob_start() and ob_clean(), for example:
ob_start();
setcookie('name', $value, time()+3600);
ob_clean();
header("Location:http://www.example.com");
Please note the upper case L in the Location header, it is very important.
A better solution might be to set the cookie on the page you are redirecting to, and pass the information to set that header through a session.
From the php manual:
setcookie() defines a cookie to be sent along with the rest of the HTTP headers. Like other headers, cookies must be sent before any output from your script (this is a protocol restriction). This
requires that you place calls to this function prior to any output, including and tags as well as any whitespace.
basically saying what you already know from your warning; that the setcookie is itself sending a header. I'd probably wonder why you want to set a cookie on a page then redirect, why not just redirect and include the data in the URL then pick it up on the target page and use the data there and/or store it in a cookie then, or store in session data if you have a session set already.

Setting cookie for site in http and https under different subdomains in PHP

Situation:
I'm trying run an https store (xcart) under one domain secure.example.com and I want to have access to a cookie it sets in http www.example.com
I'm running PHP on Apache (MAMP), testing in Firefox with Firecookie
The existing code sets cookies to .secure.example.com. I'm not sure if this is xcart related, but setcookie is actually called using secure.example.com. I'm not sure why the "." is appended.
Problems:
When I try to use setcookie in https to use the domain .example.com or just example.com, no cookie is created, whether I'm running the store under http or https. The testing code I'm using is:
setcookie('three', 'two', 0, "/", ".example.com");
If I set the cookie to secure.example.com or .secure.example.com it does show up.
Is there a reason the cookie isn't showing up?
The problem was that I was using localhost with a one word domain, 'mydomain', a fact which for some reason was edited out of the original message. At least firefox requires at least two words for an explicitly set cookie, something like mydomain.local. I changed the hosts file to have the domains: www.mydomain.local and secure.mydomain.local, and I was able to set the cookies to .mydomain.local.
Also I found that php automatically puts a "." in front of explicitly set cookies.
Yes - but the policy is determined by the browser (and on some browsers can be configured).
IIRC the semantics of the preceding . are explained in the cooke RFCs (2109 for the standard cookies states:
A is a FQDN string and has the form NB, where N is a non-empty name
string, B has the form .B', and B' is a FQDN string. (So, x.y.com
domain-matches .y.com but not y.com.)
Which I would interpret as meaning that a domian in a setcookie directive intended to be used as a wildcard match should be preceded by a '.' i.e. .example.com - however the spec goes on to say:
Domain=domain
Optional. The Domain attribute specifies the domain for which the
cookie is valid. An explicitly specified domain must always start
with a dot.
Which to me implies the opposite.
I suggest you read it yourself and experiment.
The obvious practical solution is, in the absence of a suitable cookie, to redirect back to the cookie-setting webserver for it to check its cookie then send back another redirect to the originating server with cookie details in the query string, then drop a copy of the cookie associated with the current server.
Alternatively you may get some mileage out of using FQDNs with more sections, e.g.
secure.www.example.com
and
www.example.com
(dropping the cookie for [.]www.example.com)
HTH
C.
Did you try setcookie('three', 'two', 0, "/", ".mydomain.com"); ?

Categories