I have a question about the lifetime/behavior of a session cookie
The user opens siteA.com. An authentification cookie sessionAuth=xyz is set. The cookie is HttpOnly, Secure and Expires=Session.
siteA.com redirect to siteB.org by submitting a HTTP-Form, so the HttpMethod is POST.
siteB.org does some stuff and redirects back to siteA.com, also with HTTP-Form and HttpMethod=POST.
Should the browser now send the cookie sessionAuth=xyz with this HTTP-Request?
I did some tries with Chrome 86.0.4240.111 (64-Bit), unfortunately sometimes the cookie was added sometimes not. But I couldn't figure out when/why it worked and when not.
My thoughts:
Yes, the cookie should be added because the browser was not yet closed, so the session is still valid.
No, because the cookie is from siteA.com, but the HttpPost is done by siteB.com
No, because the session is closed as soon the first redirect/form-submit happens.
What is the correct behavior?
I have the impression this worked in the past (Cookie available and added). Maybe the lastest cookie privacy changes have some impact? https://blog.heroku.com/chrome-changes-samesite-cookie
I have some questions.
Are SiteA.com and SiteB.com on the same domain ?
How you create your cookies ?
For me :
setcookie('admin_id', $result['admin_id'], time() + 28*24*3600, "/", null, false, true);
When we declare like that the cookies are valid in any part of the site.
Related
I am writing a chrome extension that makes calls to an API and for that I am trying to get some existing session cookies in the service worker. My worker makes a call like this,
const cookies = await chrome.cookies.getAll({} )
const sessionToken = cookies.filter(
cookie =>
cookie.name === "__Secure-next-auth.session-token")[0].value
However the value I get back for the cookie is different than the value in chrome dev tools. Interestingly enough both values have the same prefix (the value is long, I only pasted enough to demonstrate my point):
Dev tools cookie: eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..dCOoryziuSU3zkJl...
chrome.cookies.getAll: eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..colJ2H6th0yLZ9Q8...
In case it's useful the cookies have the HttpOnly parameter set. Can anyone guess why the cookie values might be different?
My worker is running after the page has loaded (so there's no chance that I'm getting an old value), I know the value the chrome API is giving is completely invalid because when i try to use it with the API I'm calling, I get "invalid token". On the other hand, the cookie in dev tools works with my API.
I thought maybe the cookie value had been decoded/encoded in some way but then why would the prefix match? I thought maybe the chrome API is storing multiple cookies with the same name, but when I log cookies, there is only one cookie with this name.
Would appreciate any thoughts.
I have a flask application hosted in heroku embedded as an iframe to one of my website.
Let's say a.com renders this <heroku_url>.com as an iframe.
When user visits a.com, <heroku_url>.com is rendered and session is created.
from flask import session, make_response
#app.route("/")
def index():
session['foo'] = 'bar'
response = make_response("setting cookie")
response.headers.add('Set-Cookie', 'cross-site-cookie=bar; SameSite=None; Secure')
return response
In Chrome dev tools, I see the cookie getting blocked. Works fine in firefox though.
Am I setting the cookie properly?
I understand this is due to chrome80 update, but not sure about the workaround
Setting samesite attribute in the session cookie to None seems to have solved the problem.
Had to update werkzeug (WSGI web application library which is wrapped by flask) and update the session cookie.
i.e
app.config['SESSION_COOKIE_SAMESITE'] = 'None'
app.config['SESSION_COOKIE_SECURE'] = True
However, this also depends on the user's preference in 'chrome://settings/cookies'.
Chrome will block the session cookies even if samesite is set to None if one of the below options is selected
Block third-party cookies
Block all cookies
Block third-party cookies in Incognito (blocks in incognito mode).
You can check your browser is treating the cookies as expected by checking the test site at https://samesite-sandbox.glitch.me/
If all the rows contain green checks (✔️) then there it's likely there is some kind of issue with the cookie and I would suggest checking the Issues tab and Network tab in DevTools to confirm the set-cookie header definitely contains what it should.
If there are any red or orange crosses (✘) on the test site, then something in your browser is affecting cookies. Check that you are not blocking third-party cookies (chrome://settings/cookies) or running an extension that may do something similar.
I noticed recently, that when I reboot my Tomcat web server, that the Chrome browser can no longer store cookies. i.e. tomcat uses cookies for http sessions, and the browser can no longer get its http session, also the cookie we use to store the logged in user fails, and the user does not remain logged in.
This seems to be a new issue with Chrome, perhaps from a recent update, I do not remember seeing it before. If I close the Chrome browser, then reopen it, it is fine again (until the server is rebooted again).
The issue does not happen on Firefox, seems like a bug in Chrome.
Has anyone else noticed this issue, or know of a solution?
I found some posts about Chrome/tomcat cookie issues and the suggestion to set,
sessionCookiePathUsesTrailingSlash=false in the context.xml
but this does not fix the issue.
It seems it might be related to the website supporting both https and http, and switching between the two (although it did occur on a website that did not support https as well...)
Okay, I can now recreate the issue, steps are.
connect to website via https
logout / login
connect to website via http
Tomcat JSESSIONID cookie can no longer be stored (oddly user/password cookies are stored)
This only happens on Chrome, and only since the Chrome update that add the "insecure" flag on login pages that use http
Okay I added this to my web.xml
<session-config>
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
</session-config>
This did not fix the issue, but made the issue always occur through http, i.e. make http no longer able to store the JSESSIONID cookie.
I tried <secure>false</secure> but still get the old issue.
So, it is related to this setting at least. Anyone have any ideas?
Logged bug on Chrome,
https://bugs.chromium.org/p/chromium/issues/detail?id=698741
I was able to reproduce your problem with Chrome: Just it is needed to create HttpSession from HTTPS zone. Any subsequent HTTP request will not send the session cookie and any attempt to Set-Cookie:JSESSIONID= through HTTP is ignored by chrome.
The problem is localized when the user switch from HTTPS to HTTP. The HTTPS session cookie is maintained even if server is restarted and is working properly. (I tested with Tomcat6, Tomcat 9, and using an apache proxy for SSL)
This is response header sent by Tomcat when session is created from HTTPS
Set-Cookie: JSESSIONID=CD93A1038E89DFD39F420CE0DD460C72;path=/cookietest;Secure;HttpOnly
and this one for HTTP (note Secure is missing)
Set-Cookie:SESSIONID=F909DBEEA37960ECDEA9829D336FD239;path=/cookietest;HttpOnly
Chrome ignores the second set-Cookie. On the other hand Firefox and Edge replace the Secure cookie with the not-secured. To determine what the correct behaviour should be I have reviewed RFC2109
4.3.3 Cookie Management
If a user agent receives a Set-Cookie response header whose NAME is
the same as a pre-existing cookie, and whose Domain and Path
attribute values exactly (string) match those of a pre-existing
cookie, the new cookie supersedes the old.
So, It is clear is a chrome bug, as you supposed in the question: The HTTP cookie should replace the one setted by HTTPS
Removing cookie manually from Chrome or invalidating the session at server side makes it work again (if after these actions the session is created using HTTP)
By default the JSESSIONID cookie is created with Secure when is requested from HTTPS. I guess this is the reason that Chrome do not allow to overwrite the cookie. But if you try to set <secure>false</secure> in web.xml Tomcat ignores it and the Set-Cookie header is sent with Secure
<session-config>
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
</session-config>
Changing cookie name, setting sessionCookiePathUsesTrailingSlash or removing HttpOnly has had no effect
I could not find a workaround for this issue except invalidating server session when logged user switch from HTTPS to HTTP.
Finally I opened a bug in chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=698839
UPDATED
The issue is finally marked as Won't Fix because it is an intentional change. See https://www.chromestatus.com/feature/4506322921848832
Strict Secure Cookies
This adds restrictions on cookies marked with the 'Secure' attribute. Currently, Secure cookies cannot be accessed by insecure (e.g. HTTP) origins. However, insecure origins can still add Secure cookies, delete them, or indirectly evict them. This feature modifies the cookie jar so that insecure origins cannot in any way touch Secure cookies. This does leave a carve out for cookie eviction, which still may cause the deletion of Secure cookies, but only after all non-Secure cookies are evicted.
I remember seeing this a couple of times and as far as I can remember this was the only recommendation on the matter, as you mentioned:
A possible solution to this might be adding sessionCookiePathUsesTrailingSlash=false in the context.xml and see how that goes.
Some info on the matter from here
A discussion here (same solution)
Hope I didn't confuse the issues and this helps you, let me know with a comment if I need to edit/if worked/if I should delete, thanks!
There is a draft document to deprecate the modification of 'secure' cookies from non-secure origins (submitted by Google). It specifies the recommendations to amend the HTTP State Management Mechanism document.
Abstract of the document:
This document updates RFC6265 by removing the ability for a non-
secure origin to set cookies with a 'secure' flag, and to overwrite
cookies whose 'secure' flag is set. This deprecation improves the
isolation between HTTP and HTTPS origins, and reduces the risk of
malicious interference.
Chrome already implemented this feature in v 52 and same feature is also implemented in Mozilla few days back.
To solve this issue, I think you should connect to website via https only.
The bad way I think is to set sessionCookieName = "JSESSIONIDForHttp" in context.xml
Let Browser's cookie know:
If secure https condition use default "JSESSIONID".
If not secure http condition use "JSESSIONIDForHttp".
I am working on a spring MVC app and found a strange issue that only happen on chrome. The logic is:
user request a list of items
user click on add new button and a bootstrap dialog popup allow user type in the name
on submit, a post request sent to the server
server create an new item and save it to db
server store the new item id to cookie and send a redirect response to browser
browser request item view page
server pick up the item id from cookie and render the page
The above logic runs good on nearly all browsers (I didn't test on IE) except chrome. I found the root cause is chrome will store previous cookie with a different item id and at step 6 chrome send duplicate item id cookies to the server.
Any idea how to resolve this issue?
Chrome[Version 32.0.1700.41 m Aura]
Opera[Version 20.0.1353.0]
Firefox[Version 29.0a1 (2013-12-10)]
Safari[Version 5.1.7 (7534.57.2)]
No screen capture. But it works
Restart Chrome!
At some point (even today this happened to me) Chrome is getting confused on what cookies a domain has in its memory vs cached on disk. This confusion leads to cookies being added but not removed from what I can tell. In my case, I'm Suspecting McAfee locking files for scanning. Restarting Chrome rebuilds the cache and then works.
https://bugs.chromium.org/p/chromium/issues/detail?id=17855
https://bugs.chromium.org/p/chromium/issues/detail?id=273873
I had something along this stored in my Chrome cookies :
1st cookie : (it was set to expire)
Site : dashboard.app.localhost
Value : access-token=123456; Domain=.app.localhost; Path=/; HttpOnly; SameSite=Strict
2nd cookie : (session cookie that shouldn't be there, I had to dig in the Chrome settings to find it)
Site : dashboard.app.localhost
Value : access-token=invalid; Domain=api.app.localhost; Path=/
Apparently the second cookie appeared due to an error on my side. However, Chrome sent it alongside the first one, creating this header :
Cookie: access-token=invalid; access-token=123456
The solution I found :
Manually delete the second cookie in the Chrome settings.
I am working on a C++ windows phone application that uses IXMLHTTPRequest2 to perform HTTP Requests. I have run into a situation in my app where I want to remove one of the HTTP cookies that the server assigned to the session. The cookie is used for authentication, and I want to remove it to force a new logon.
I could not find a method to remove a cookie, and when I tried to overwrite the cookie with a new value, it did not work.
The original value of the cookie was set with the set-cookie header:
Set-Cookie: XYZ=9c2725ec03169f17345525d5f4f58455e445a4a42;Secure;Path=/
I tried to manually inject my own expiring cookie in this format:
XYZ=xyz;Path=/;expires=Wednesday, 09-Nov-1999 23:12:40 GMT;
However, when the next request was sent, it still used the original cookie sent by the server. Is there any way that I can properly accomplish this.
Thanks
Ok, I figured it out. Looks like I was just setting the cookie incorrectly:
XHR_COOKIE xhrCookie = {0};
xhrCookie.pwszUrl = url;
xhrCookie.dwFlags = XHR_COOKIE_IS_SESSION;
xhrCookie.pwszName = L"XYZ";
xhrCookie.pwszValue = L"xyz;expires=Wednesday, 09-Nov-1999 23:12:40 GMT;";
DWORD dwCookieState=0;
m_xhr->SetCookie(&xhrCookie , &dwCookieState)