I know how the cookies work, just started to dig why Codeigniter does not store generated csrf token in SESSION, it just store in cookie. Concerned about security, I'v started to think about php setcookie() function params such as path and domain. And I have asked myself is it possible to set 'evil_cookie' with a path='/' and domain = 'www.goodsite.com' from another domain, from some 'www.evilsite.com'? And another question is, will 'evil_cookie' be sent to 'www.goodsite.com' when performing request to 'www.goodsite.com'?
So, I did a test. I'v created 'set_cookie.php' file and uploaded it to some 'www.evilsite.com':
setcookie('evil_cookie', 'gotcha', time() + 60 * 30, '/', 'www.goodsite.com');
I was using Firefox and Firebug + Cookie plugins for viewing sent and received cookies. So, I did receive 'evil_cookie' after the request to 'www.evilsite.com/set_cookie.php'. However, the cookie was not saved (at least there was no such cookie when viewing in firebug cookie plugin panel). Nor it was sent when requesting again to "www.evilsite.com/set_cookie.php". Just received but not saved.
From the Firefox browser point of view, it's logical and secure to save cookie for current domain only. IMHO those set cookie() params such as path and domain are primarily for managing cookies for current domain and its subdomains but not for external domains. I was a little bit upset I was unable to find related info on php.net, so I'm not sure is it a browser related behavior and specifics how it deals with "3rd party cookies" or it's more a standard? Does all browsers behave the same? If there's any solid and reliable source for such statements please share.
That is also relevant to another use of cookies - store session data (without using PHP native sessions, for example Codeigniter does so). So, if all browsers do not allow to safe cookie with other than current domain then It's OK. However, it does not protect from CSRF as 'www.evilsite.com' might contain evil javascript code that will create 'evil_cookie' directly on the client when a user will perform and get a request from 'www.evilsite.com'.
Cookies are subject to the same origin policy: a site can only write and read cookies for its own domain.
Cookies can only be set for the current domain or its subdomains as you have alredy found out (otherwise, anyone could replace anyone else's cookie; chaos would ensue). This is enforced by the browser: if you attempt to set cookies for another domain from the server side (using an HTTP header) the browser will ignore the cookie. If you attempt to do the same from the client side (using Javascript), the same origin policy will prevent you from doing so.
Therefore, www.evilsite.com can set a cookie for its own domain with Javascript, but that's not an issue: it could already do that using an HTTP header. There's no new attack vector here.
[…] is it possible to set 'evil_cookie' with a path='/' and domain = 'www.goodsite.com' from another domain, from some 'www.evilsite.com'?
No, user agents should ignore Set-Cookie directives with Domain attributes that do not domain-match the current requested domain:
The user agent will reject cookies unless the Domain attribute
specifies a scope for the cookie that would include the origin
server. For example, the user agent will accept a cookie with a
Domain attribute of "example.com" or of "foo.example.com" from
foo.example.com, but the user agent will not accept a cookie with a
Domain attribute of "bar.example.com" or of "baz.foo.example.com".
Such cookies would not even be accepted by user agents. Similar applies to the Path and Secure attributes.
See also How do browser cookie domains work? for examples of how the Domain attribute values are interpreted by user agents.
Related
Say I have a website called a.com, and when a specific page of this site is loaded, say page link, I like to set a cookie for another site called b.com, then redirect the user to b.com.
I mean, on load of a.com/link I want to set a cookie for b.com and redirect user to b.com.
I tested it, and browser actually received the cookie from a.com/link, but it didn't send that cookie on the redirection request to b.com. Is it normal?
Can we set cookies for other domains?
You cannot set cookies for another domain. Allowing this would present an enormous security flaw.
You need to get b.com to set the cookie. If a.com redirect the user to b.com/setcookie.php?c=value
The setcookie script could contain the following to set the cookie and redirect to the correct page on b.com
<?php
setcookie('a', $_GET['c']);
header("Location: b.com/landingpage.php");
?>
Similar to the top answer, but instead of redirecting to the page and back again which will cause a bad user experience you can set an image on domain A.
<img src="http://www.example.com/cookie.php?val=123" style="display:none;">
And then on domain B that is example.com in cookie.php you'll have the following code:
<?php
setcookie('a', $_GET['val']);
?>
Hattip to Subin
Probaly you can use Iframe for this. Facebook probably uses this technique. You can read more on this here. Stackoverflow uses similar technique, but with HTML5 local storage, more on this on their blog
In case you have a.my-company.com and b.my-company.com instead of just a.com and b.com you can issue a cookie for .my-company.com domain - it will be accepted and sent to both of the domains.
You can't, at least not directly. That would be a nasty security risk.
While you can specify a Domain attribute, the specification says "The user agent will reject cookies unless the Domain attribute specifies a scope for the cookie that would include the origin server."
Since the origin server is a.com and that does not include b.com, it can't be set.
You would need to get b.com to set the cookie instead. You could do this via (for example) HTTP redirects to b.com and back.
Setting cookies for another domain is not possible.
If you want to pass data to another domain, you can encode this into the url.
a.com -> b.com/redirect?info=some+info (and set cookie) -> b.com/other+page
see RFC6265:
The user agent will reject cookies unless the Domain attribute
specifies a scope for the cookie that would include the origin
server. For example, the user agent will accept a cookie with a
Domain attribute of "example.com" or of "foo.example.com" from
foo.example.com, but the user agent will not accept a cookie with a
Domain attribute of "bar.example.com" or of "baz.foo.example.com".
NOTE: For security reasons, many user agents are configured to reject
Domain attributes that correspond to "public suffixes". For example,
some user agents will reject Domain attributes of "com" or "co.uk".
(See Section 5.3 for more information.)
But the above mentioned workaround with image/iframe works, though it's not recommended due to its insecurity.
You can't, but... If you own both pages then...
1) You can send the data via query params (http://siteB.com/?key=value)
2) You can create an iframe of Site B inside site A and you can send post messages from one place to the other. As Site B is the owner of site B cookies it will be able to set whatever value you need by processing the correct post message. (You should prevent other unwanted senders to send messages to you! that is up to you and the mechanism you decide to use to prevent that from happening)
Send a POST request from A. Post requests are on the serverside only and can't be accessed by the client.
You can send a POST request from a.com to b.com using CURL (recommended, serverside) or a hidden method="POST" form (clientside). If you go for the latter, you might want to obfuscate your JavaScript so that the user won't be able to understand the algorithm and interfere with it.
Make a gateway on b.com to set cookies:
<?php
if (isset($_POST['data']) {
setcookie('a', $_POST['data']);
header("Location: b.com/landingpage");
}
?>
If you want to bring security a step further, implement a function on both sides (a.com and b.com) to encrypt (on a.com) and decrypt (on b.com) data using a cryptographic cypher.
If you're trying to do something that must be absolutely secure (e.g. transfer a login session) try oAuth or take some inspiration from https://api.cloudianos.com/docs#v2/auth
Here is what I've used. Note, this cookie is passed in the open (http) and is therefore insecure. I don't use it for anything which requires security.
Site A generates a token and passes as a URL parameter to site B.
Site B takes the token and sets it as a session cookie.
You could probably add encryption/signatures to make this secure. Do your research on how to do that correctly.
In this link, we will find the solution Link.
setcookie("TestCookie", "", time() - 3600, "/~rasmus/", "b.com", 1);
I have a script that i server to my clients. Now without going into details the script is looking if the user has a cookie from a certain domain (my domain) and if the user has the right cookie some data and features are given to the user.
Now for secruity reasons me and my company had to change our base url address of the place where cookie is set.
Now even though the above seems rather strange i can ensure you that my question is fairly simple:
Is it possible to change the url of a cookie and if so how?
The browser only sends the cookies of the corresponding domain, so you have to create the cookies again, from a php script on the new domain.
Over the past 3 days I've been getting the "Disallowed Key Characters" error from CodeIgniter's Input class. I've found that this is resulting from CI checking for valid global cookie keys in the $_COOKIE array. The particular keys tripping the alert are below (where asianfanfics.com is the site I'm working on):
ebNewBandWidth__www_asianfanfics_com=277%3A1357053922099;expires=Wed,_01_Jan_2014_15:25:24_GMT;_path=/;_domain=_www_asianfanfics_com
ebPanelFrequency__www_asianfanfics_com=\"\";expires=Tue,_01_Jan_2013_15:43:39_GMT;_path=/;_domain=_www_asianfanfics_com
So if $_COOKIE[$key] = $value, $key is not passing CI's check and $value is always empty. When inspecting that cookie on Chrome's cookie inspector, I see that it is set for the www subdomain and under expires, instead of a date, it says "session".
The only other question on SO relating to this is due to someone using the jQuery Tabs plugin which I'm not using.
Does anyone know what could be setting this cookie?
By the name of the cookies (starting with ebNewBandWidth and ebPanelFrequency), you might want to ask LinkedIn if their servers have injected some code into client resources served by your server or otherwise connected to your website or domainname it is served from that has created these cookies:
LinkedIn Corporation
Attn: Privacy Policy Issues
2029 Stierlin Court
Mountain View,CA 94043
USA
http://www.linkedin.com/static?key=privacy_policy
Might because generally everybody can set everything which is acccepted as a valid cookie name from the browser requesting with such cookie request headers.
Session in that cookie means, it will expire when the browser is closed.
The rest looks like that Codeigniter is dropping that cookie for some reason. Probably only a pre-caution.
Any HTTP client can send any kind of cookie request headers to your server, so there is nothing you can do against that.
The cookie is always set by the user-agent, at least the cookie in the request that is causing the error (what goes into $_COOKIE).
Which process originally has set this specific cookie can not be said by the name of the cookie only. Any process can create any kind of cookie header, and the cookie seems at least valid enough to make the browser send it with the requests.
Probably Codeigniter needs some fix or setting here so you can make use of such keys, e.g. you might want to disable that (in your case useless?) check.
I believe MediaMind formerly EyeBlaster (hence eb prefix to cookies) is behind these cookies. Their service is widely used by banner adservices, so they may well be involved indirectly by a service your site uses. The infiniti cookie page referred to above links them to ebNewBandWidth.
I was brought aware of this issue by some users on my website. A user many enter into their browser http://xxxx.com and then login. Then they may click on a link that brings them to http://www.xxxx.com it asks them to login again! Is this a known issue that anyone has encountered before? I tried googling it but im not sure if im using the wrong keywords or what because i cannot find anything related to this.
Thanks,
Ian McCullough
As far as your browser is concerned, www.xxxx.com and xxxx.com are different domains. The same-origin policy prevents accessing cookies across domains.
However, the browser is aware of subdomains, and a subdomain can access the cookies of a parent domain. So, if you want to make your cookie accessible to both xxxx.com and www.xxxx.com, just set your cookie on .xxxx.com and you'll be set.
When you set a cookie, you can optionally specify which domain the cookie is set for. If you don't, the cookie is particular to that hostname only, and thus if the cookie is set on www.example.com, it will only be returned by the browser on that hostname or below.
If, when setting the cookie, you set the domain to "example.com" it should work also on "www.example.com".
The problem is that the more specific cookie will override the less specific one, so if you've previously set a cookie on "www.example.com" it will continue to override the new one set for "example.com", rather than being replaced by it - you would first have to delete the one set for "www.example.com". It gets tricky since when the client returns a cookie to the server it doesn't say which hostname the cookie was set for.
People seem to be assuming you're using a cookie to perform authentication but are skipping what appears to be your root question. Trevor briefly touched on it, but still kept to the cookie concept. As far as http is concerned, www.xxxx.com and xxxx.com are different subdomains on the same top level domain. Hence, while they may be the same ip, same website, same everything, the browser request and the server's response are considered to be 2 separate domains/sites. Sessions are not shared across subdomains unless you have a separated session state (such as a SQL Session store, etc).
However, if you are using cookies for authentication, you can add a check for the cookie and rebuild a fresh session if the data in the cookie is valid (and sufficient to reconstruct session). Otherwise you'll have to separate session state from the process into a data store.
Check the domain of the cookie, when creating a cookie you can specify if it is for all sub domains, the root server, specific sub domain, etc. To handle all, the cookie would be for .example.com
Here's the quick version of my question:
Is it possible to set a cookie somehow into a client's browser when the cookie is for use with a different server (in this case an Exchange mail server)? In this scenario the server trying to set the cookie is at "intranet.myschool.edu" and the exchange server is at "owa_server.myschool.edu".
Here's the full question:
I have a php script that uses cURL to make an HTTP POST to our Exchange server that has Forms Based Authentication enabled.
When I make a successful HTTP POST (which includes the user/pass in the posted url), the Exchange Server (or more specifically, the https://my.school.edu/exchweb/bin/auth/owaauth.dll file) outputs cookies.
Specifically, it outputs a "sessionid" and a "cadata" id.
With these cookie ids written to a text file on the server, cURL/PHP can reference it and then request data (via webdav and such) from the Exchange/OWA server.
That part works.
The problem I'd like to solve is now passing the cookie ids to a clients browser, so that they can use these cookie ids to auto-login to their own OWA account.
In essence I would like our users to log into our intranet with their Active Directory IDs, and see a snapshot of their recent emails. Then, if they need to, I'd give them a little link to switch over to the full OWA web application. When this switch happens, I don't want them to have to login to the OWA manually. Since they already submitted their Active Directory UserName and password at the front of the intranet, I'd like them to be auto-logged into the OWA.
I should note that using Windows Authentication to try to do single sign on is not possible since we have a mix of Mac OS, Windows, and Linux.
I had thought that I would be able to do a "setcookie" and assign the cookie ids that cURL got and put them into the clients browser.
Is this not possible? Is it not possible to "spoof" Exchange/OWA (or any other site) this way.
I have legitimate cookie ids that cURL captured. Is there no way to pass these to a client browser on a different computer?
In a worst case scenario, would using Javascript to just auto paste the username and password into the OWA login page be my only hope?
Does anyone have any other ideas on how to avoid my double login problem with Exchange/OWA?
Thanks for any help provided!
From RFC 2965 (NB HDN = "host domain name)
Host A's name domain-matches host B's
if
* their host name strings string-compare equal; or
* A is a HDN string and has the form NB, where N is a non-empty
name string, B has the form .B', and B' is a HDN string. (So,
x.y.com domain-matches .Y.com but not Y.com.)
Note that domain-match is not a
commutative operation: a.b.c.com
domain-matches .c.com, but not the
reverse.
So using .myschool.edu as the domain should work. NB the leading . is essential
You may be able to set a cookie with a domain part of '.myschool.edu'. In theory that's then sent to any other site hosted under a subdomain of 'myschool.edu'.
In practise however, your client software may decide that the cookie's scope is too wide, and refuse to send it back.
I think this would be a serious security loophole if it were possible...
In this scenario the server trying to set the cookie is at "intranet.myschool.edu" and the exchange server is at "owa_server.myschool.edu".
You should be able to do that.
I do this on my site (which I will change the names for the purpose of the example):
I have a web app at url
webapp.domain.com
And when users login, I set the cookie of the PunBB forum package which is at:
forum.domain.com
By setting/clearing the PunBB forum cookie, I can automatically login/logout my users on their forum account for convenience (this of course assumes that the registrations are syncrhonized, in my case I removed the forum registration and the main site registration creates the forum account for the user).
All you need to do is in subdomain#1 to set the cookie path to "/" (the default), and set the cookie domain to "domain.com". Then your app in subdomain#2 should see the cookie.
EDIT: I see barrowc has answered, I've seen the ".domain.com" pattern in some examples, my site uses "domain.com" for the cookie domain and it works too (maybe php set_cookie adds the leading dot if missing?)
Your browser gets to decide that... but usually no, you cannot. That is considered a type of XSS vulnerability.
you could use an iframe to set the cookie, ie. have an iframe on your web server that makes a request to a page on your exchange http server (https://my.school.edu/exchweb/) with your wanted cookie vars set as get or post variables. then use the vars to set the cookie for that domain, and redirect the user to the exchange server.
now, there could be logic on the backend of OWA that checks ip address, user agent, etc.... when registering the session that may invalidate this..... not sure
We've been fighting this one hard for months, the best we can come up with is allowing the web server to get the cookie for Exchange at EVERY LOGIN. problem is, that without cookie affinity, we don't have a way to make sure that the cookie obtained by the web server came from the same load balanced node that the client connects to.