Why does cookie have to have secure=true when SameSite=none? - http

I don't see the security concern when I do secure=false and SameSite=none. If a sensitive cookie is sent over http, anyone can intercept it, and forge a request on their own computer. Of course, because its their own computer, they can spoof the origin to get around SameSite. So SameSite=Strict provides no protection if secure=false. I don't see why it's not allowed to set secure=false and SameSite=none.

See this from the chromium team: https://chromestatus.com/feature/5633521622188032
Also, you either set the "secure" flag or not, you don't set "secure=false" or "secure=true".

Related

Set-Cookie is stopping me from logging into WordPress

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.

Chrome's Advanced REST Client doesn't mind CORS restrictions, how?

I developped a client and a server app. In the server's Web.config, I set the property
<add name="Access-Control-Allow-Origin" value="http://domain.tld:4031" />
And, indeed, when I try connecting with a client installed in a different location, I get rejected. But I do not get rejected when I use Chrome's Advanced REST Client from the very same location!
In the extensions, the header of the response indicates
Access-Control-Allow-Origin: http://www.domain.tld:4031
So how comes I still get a answer "200 OK", and the data I requested?
UPDATE:
I do not think this topic is enough of an answer : How does Google Chrome's Advanced REST client make cross domain POST requests?
My main concern is : how comes is it possible to "ask" for those extra permissions. I believe the client shouldn't be allowed to just decide which permission it receives. I thought it was up to the server only. What if I just "ask" for extra permissions to access your data on your computer? It doesn't make sense to me...
The reason that the REST client (or really the browser) is able to bypass the CORS restriction is that it is a client side protection. It isn't the responsibility of the server to provide this protection but it is a feature implemented by most modern browser vendors to protect their users from XSS-hazards.
The following quote from the Wikipedia CORS page sums it up quite good
"Although some validation and authorization can be performed by the server, it is generally the browser's responsibility to support these headers and respect the restrictions they impose." - Wikipedia
You could of course, like the quote imposes, do some server side validation on your own. The "Access-Control-Allow-Origin" header however is more of a indication to the browser that is is okay for the browser to allow the specified origins. It's then up to the browser to decide if it want's to honor this header. In previous versions of for example chrome there actually existed a flag to turn off the same origin policy all together.

Cookies received from Server is Secure But Cookies sent to Server is not secure ASP.NET

In my ASP.NET Web application, i have made the below changes to make the ASP.NET_SessionID and .ASPXAUTH Cookies Secure by adding the below entries to web.config
<httpCookies httpOnlyCookies="true" requireSSL="true" />
and adding the below tag
<forms requireSSL ="true" />
But my issue here is that, the Cookies received from Server(Network->Cookies->Direction Column has a value of received) has Secure and HttpOonly flag set to true. Found the information when i debug using IE 11 Developer tools, but the cookies data sent to Server(Network->Cookies->Direction Column has a value of Sent) does not have any Secure or HttpOnly flag set to true.
Is this the default behaviour? If so, why the data sent to server is not having the Secure and HttpOnly flag set? How to set it other than the above changes made to the config file.
Cookie flags, like Secure and HttpOnly, are only sent from the server to the client. You won't ever see them in traffic going the other way. If you want to make sure that a cookie is Secure, have the browser make a request over HTTP (instead of HTTPS) and see if the cookie is still present (it shouldn't be). If you want to make sure a cookie is HttpOnly, open your site in the browser and then check the value of document.cookie using the JS console in the dev tools; you should see any non-httponly cookies you have but no httponly cookies.
Cookies are an inherently client-side thing. They are a way for a server to tell the client "every time you make a request to me, include this bit of info". The Secure flag modifies that to say "Every time you make a request to me over a secure connection, include this bit of info (but don't ever divulge it over insecure connections)". A conforming user agent - that is to say, a web browser - is supposed to obey those directives. However, there are no equivalent directives the other way; servers don't have to do anything at all with cookies the client sends them, and there is no "client sets a cookie on the server" equivalent of the way servers can set cookies on the client. Directives (including Secure, HttpOnly, Domain, Expires, etc.) are only used when setting a cookie.

Cookies from https to http works sometimes, sometimes not

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

Is domain attribute of a cookie sent back to a server?

If evil.example.com sets a cookie with a domain attribute set to .example.com, a browser will include this cookie in requests to foo.example.com.
The Tangled Web notes that for foo.example.com such cookie is largely indistinguishable from cookies set by foo.example.com. But according to the RFC, the domain attribute of a cookie should be sent to the server, which would make it possible for foo.example.com to distinguish and reject a cookie that was set by evil.example.com.
What is the state of current browsers implementations? Is domain sent back with cookies?
RFC 2109 and RFC 2965 were historical attempts to standardise the handling of cookies. Unfortunately they bore no resemblance to what browsers actually do, and should be completely ignored.
Real-world behaviour was primarily defined by the original Netscape cookie_spec, but this was highly deficient as a specification, which has resulting in a range of browser differences, around -
what date formats are accepted;
how cookies with the same name are handled when more than one match;
how non-ASCII characters work (or don't work);
quoting/escapes;
how domain matching is done.
RFC 6265 is an attempt to clean up this mess and definitively codify what browsers should aim to do. It doesn't say browsers should send domain or path, because no browser in history has ever done that.
Because you can't detect that a cookie comes from a parent domain(*), you have to take care with your hostnames to avoid overlapping domains if you want to keep your cookies separate - in particular for IE, where even if you don't set domain, a cookie set on example.com will always inherit into foo.example.com.
So: don't use a 'no-www' hostname for your site if you think you might ever want a subdomain with separate cookies in the future (that shouldn't be able to read sensitive cookies from its parent); and if you really need a completely separate cookie context, to prevent evil.example.com injecting cookie values into other example.com sites, then you have no choice but to use completely separate domain names.
An alternative that might be effective against some attack models would be to sign every cookie value you produce, for example using an HMAC.
*: there is kind of a way. Try deleting the cookie with the same domain and path settings as the cookie you want. If the cookie disappears when you do so, then it must have had those domain and path settings, so the original cookie was OK. If there is still a cookie there, it comes from somewhere else and you can ignore it. This is inconvenient, impractical to do without JavaScript, and not watertight because in principle the attacker could be deleting their injected cookies at the same time.
The current standard for cookies is RFC 6265. This version has simplified the Cookie: header. The browser just sends cookie name=value pairs, not attributes like the domain. See section 4.2 of the RFC for the specification of this header. Also, see section 8.6, Weak Integrity, where it discusses the fact that foo.example.com can set a cookie for .example.com, and bar.example.com won't be able to tell that it's not a cookie it set itself.
I would believe Zalewski's book and his https://code.google.com/p/browsersec/wiki/Main over any RFCs. Browsers' implementations of a number of HTTP features are notoriously messy and non-standard.

Resources