I have a website with a login form in https which sets a session id in a cookie. For some reasons, the rest of the webpage is a cgi-script from http. However, when accessing the cookie from http, it sometimes work, sometimes not, although I can clearly see the cookie is set to correct session id in the browser. I have not yet discovered a pattern. Am I missing something?
https://mypage.com/secure/login.php
http://mypage.com/cgi-bin/script
I set the cookie path to "/", which should do the trick, right? Domain is set to ".mypage.com". Secure only is false, http only false.
Tested with Firefox and Chromium.
Regards
Olle
Related
I have a web server which returns 200 OK with a bunch of set-cookies, and an HTML page which loads a bunch of scripts from the same server.
However, the subsequent loads that was spawned from that HTML page submits a different cookie on their HTTP request headers.
What could be causing that? Surely there's some policy I'm missing out on, but I don't see why it works on some pages and not others?
I'm using chrome as the browser, but this behavior also happened from iOS, so I'm guessing it's not browser specific.
So after a lot more reading and troubleshooting, it turns out that when you don't set a cookie path, it'll default to whatever path the original request set-cookie was sent to. And because my resource paths had a different path, the cookie was not sent.
Adding Path=/ fixed it for my issue. Of course, if you don't want your cookie to be accessible to all pages this is bad, but my web-server requires requests to come with cookies because they are sensitive data (for security reasons).
I am running WordPress 5.3.2 on Apache/2.4.29 (Ubuntu) 18.04 on a Digital Ocean droplet.
My client requested the following:
All cookies transferred over an encrypted session, in particular session cookies, should be marked as 'Secure' and all session information should be transmitted over HTTPS.
The HttpOnly flag should also be set within the cookie
So, I defined the following in the virtual host:
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure;SameSite=Strict
I then tested the header response and could see my Set-Cookie defined.
The problem is, I now can't login to WordPress. WordPress says:
ERROR: cookies are blocked or not supported by your browser. You must
enable cookies to use WordPress.
What am I doing wrong?
Strict is probably more restrictive than you want, as this will prevent cookies from being sent on initial cross-site navigations, e.g. if I emailed you a link to a page on your blog, when you first followed that link, the SameSite=Strict cookies would not be sent and it might appear as if you were not logged in.
SameSite=Lax is a better default here. Then I would explicitly look at setting SameSite=Strict or SameSite=None on individual cookies where you know the level of access required.
The HttpOnly attribute is also blanket preventing all of your server-side set cookies from being read by JavaScript. You may well have functionality on your page that requires this.
Finally, a blanket approach here is probably overkill - as it looks as if you will be appending this snippet to every outgoing cookie header, even the ones that already include those attributes. This is likely to cause some unpredictable behaviour. I would either do this on a specific allow-list basis by checking for explicit cookie names or I would alter the regex to only set this if those attributes are missing.
A late answer. But if it helps someone:
Put these values in php.ini
session.cookie_httponly = 1
session.cookie_secure = 1
Of course you should have a valid https certificate.
Everyone claims a domain must have two dots in order for a cookie to be stored, but that cannot be true, because Chrome is storing the cooking named "__RequestVerificationToken" received through the Set-Cookie header from ASP.NET; however, it refuses to store other cookies. I literally am sending a virtually identical cookie with a virtually identical Set-Cookie header, and yet Chrome is refusing to store it. The path is "/", just like the other one. No domain is set. The only difference is the name. Is Chrome giving "__RequestVerificationToken" some kind of special treatment?
Looks like Chrome will save "session" cookies for "localhost", but not "permanent" cookies. No idea why it makes the exception for "session" cookies, but the "permanent" ones aren't stored because cookies are only supposed to be stored for 2nd level domains (domains with at least 2 dots, which localhost is not).
"permanent" cookies are cookies that DO set an expiration date, which is a bit counter-intuitive, but they're "permanent" in the sense that they survive across browser restarts unlike "session" cookies which are supposed to be deleted when the browser closes. In reality, they're all relatively permanent, because Chrome/Firefox typically don't delete the session cookies when the browser closes, thanks to features like "continue where I left off" and "restore my tabs when the browser restarts".
Another takeaway is that we may as well not set an expiration on any kind of session or auth cookie at all, because it offers the following advantages: 1. it works on localhost, 2. it more secure in that they stand a chance of being deleted when the browser closes, and 3. they persist across browser sessions anyway if the user has the browser configured to do so, so setting a long timeout isn't necessary. Setting an expiration on the cookie also doesn't do you any good anyway, because it's just another value to sync with the server-side session, the value isn't sent to the server with the cookie anyway, so it's useless, and utimately the server-side expiration for the token (stored in session or database) is authoritative anyway. So just don't set an expiration on your session or auth-related cookies.
Is there any case where the browser is sending an HTTP request to a server but does not attach cookies associated with that domain to the request? If so, what are the cases?
Cookies are set by the server first, or are set by a javascript that is executed in a page from that domain. So every cookie you get, it a cookie you have set earlier.
Normal cookies are sent to the server with each request, Ajax as well as regular page loads and posted data. There are some new features like offline storage that is implemented by more and more browsers, but those features are not cookies.
A cookie can have a domain and path associated with it, thus limiting which resources the cookies are sent to.
document.cookie = 'name=value; expires=' + date.toGMTString() + '; path=/myFolder; domain=myDomain';
Yes.
Chrome (as of version 25) does not include cookies in favicon requests. Also, it is apparently standard for other browsers to not share cookies between the favicon requests and other requests.
I've run into a problem where login on my site is not working consistently in IE8. It works fine in Firefox/Chrome/Safari but not IE8.
On first login everything is fine. After logging out and trying to log back in it usually fails for a while. It will end up redirecting to the login page against after authentication.
So the authentication is successful, it returns true, but it seems IE8 is not accepting the new value for the session id which we set by returning:
Set-Cookie SESSIONID=........; Path=/
in the response header. But obviously this works with a clear cache and I can get in fine. But after its already there it fails to reset, so after authenticating and attempting to go to a new page it sees this is an old session id being sent from the browser and redirects to the login page.
I haven't found anything here or elsewhere that really solves this (besides clearing the cache). Most references to IE8 cookie problems are language/framework specific and don't answer this problem.
Is there something special I might need to do with the set-cookie to make this work?
UPDATE:
I've set IE8 to prompt before accepting any cookie. When the login works fine it prompts as expected. When it does not work there isn't even a prompt to except the cookie..
UPDATE 2:
I should have mentioned that the cookie is expected to be set after an ajax call:
$.get(authenticate_url, ....)
The url it requests a response from returns the header that sets the session id, then in the callback function the user is redirected to the main page -- assuming login is successful.
Is it a first party cookie or a 3rd party cookie. If the latter, ensure you're sending a P3P header.
Are you setting the HTTPOnly attribute?
Are you sure that the domain for the cookie is always the same? E.g. if you set the cookie when visiting "example.com" and tried to change it from "www.example.com" then you'll encounter problems.
I've hit similar symptoms when I have cookies set for both www.example.com and example.com. If there's no domain explicitly set, then session cookies get set for both.
However, higher-level domain cookies take precedence over the lower domian. So, if www.example.com tries to set a cookie, but example.com already has, then the example.com cookie stays in place and continues to apply for www.example.com.
There are two ways to approach this problem. One is not to allow access both with and without the www subdomain. Redirect one to the other. The second is to explicitly set the cookie domain, so that there aren't two versions lying around.
Of course, that might not actually be your issue. Experiment and find out :)