Spring Security CSRF Cookie ignored by chrome - spring

I am trying to implement CSRF protection using spring and angular. In Spring, I configured:
CookieCsrfTokenRepository cookieCsrfTokenRepository = new CookieCsrfTokenRepository();
cookieCsrfTokenRepository.setCookieHttpOnly(false);
cookieCsrfTokenRepository.setCookiePath("/");
cookieCsrfTokenRepository.setCookieName("test");
cookieCsrfTokenRepository.setHeaderName("test");
Which works as can be seen in the server's response:
Response headers showing Set-Cookie: test=....
But somehow the cookie is not being set. When looking at my the cookies for the website or even all cookies of Chrome which I freshly cleaned before, there simply are no cookies at all:
No cookies shown by chrome
The setting in Chrome is "Allow all cookies".
I read that the set-cookie header sometimes causes troubles on localhost and without https, so I also tried on my deployment server with the same result unfortunately. Any ideas on why that happens?

Related

iframe refused to connect while using XAMPP and Laravel

I am developing a Laravel application and have added an iframe as follows:
The iframe does not connect and simply says www.google.com refused to connect. I have done some research and it appears this related to X-Frame-Options being set. Within the Chrome Browser Developer Tools, I see the following error message:
A cookie associated with a cross-site resource at https://www.google.com/ was set without the SameSite attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with SameSite=None and Secure. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.
My guess is this is a setting that needs to be changed at the XAMPP server level within Apache but I cannot figure out where. Any ideas?
If you are testing on localhost and you have no control of the response headers, you can disable it with a chrome flag.
open this URL :
chrome://flags/#same-site-by-default-cookies
and disable SameSite by default cookies
SameSite prevents the browser from sending the cookie along with cross-site requests.
if you don't want to disable SameSite by default cookies you can add response header before sending back response to resolve this:
return response($content)
->header("Set-Cookie", "HttpOnly;Secure;SameSite=Strict");

Cannot set cookie in browser but working with postman

I am trying to set a cookie using go in the chrome browser but can only get it to set in postman.
The cookie successfully sets in postman but is simply not setting in chrome with no error.
I have set CORS as default using this package https://github.com/gin-contrib/cors as I have had issues with CORS requests in the past and this seemed to solve the issue.
I set the cookie using:
c.SetCookie(
"TOKEN",
tokenString,
3600,
"/",
"localhost",
false,
true)
I have tried replacing localhost with http://127.0.0.1 which again works in postman but not chrome or firefox. I have also tried setting the cookie with the http package instead but this has failed in the same way.
EDIT I have also tried domain as blank ("") but this has the same outcome.
You passed true to the secure argument of SetCookie but you're sending the cookie to an insecure http address.
As per the MDN docs:
A secure cookie is only sent to the server with an encrypted request over the HTTPS protocol.

Does Google Chrome have different rules for cross-domain cookies in ajax requests in Incognito mode? If so, how do I find those rules?

I have multiple subdomains in my app. There is a parent domain cookie for user logins/session, and a subdomain cookie for cross site request forgery protection (CSRF). Requests go between subdomains using cross origin resource sharing (CORS), using the login/session cookie for all subdomains.
main.foo.com is where the user logs in. The login/session cookie uses the domain foo.com.
app.foo.com is where a large portion of the app resides. This is the active page when my error occurs.
message.foo.com is used for sending messages between users. It is its own django app, with a csrf cookie using domain message.foo.com for use with its forms. It also uses the login/session cookie from foo.com.
So the user is on app.foo.com/index.php and an ajax POST needs to go to message.foo.com. The browser has made ajax GET requests to message.foo.com, which have set the CSRF cookie. The ajax POST is sent with proper CORS headers.
If I disable CSRF in the Django view using #csrf_exempt decorator, then the missing cookie is ignored and the POST is processed fine. Otherwise, I get the 403 error for CSRF.
The CSRF cookie is sent from Firefox and Chrome in normal mode. When Chrome is Incognito, the CSRF cookie is not sent.
From what I can tell, the difference between the cookies is their domain. The login/session cookie is set to foo.com, so all subdomains use it. The CSRF cookie is set by message.foo.com so it should only be sent back to that domain. But even when the request is going to message.foo.com, Chrome Incognito does not send the cookie. It may not have even accepted the cookie. (It's hard to tell if it didn't accept the cookie or if it's just not sending it back.)
This cookie scenario seems legit. The cookie is being sent back to the subdomain which set it. No other subdomains are trying to read or modify the cookie. The origin sending the request has been authorized with CORS headers.
Why does Chrome not send that cookie? Is this behavior documented somewhere?
Sorry, Stack Overflow. This question isn't actually about what I thought it was.
The problem is that I did something in my Django code which was stopping the CSRF cookie from being sent to the browser. The non-incognito browsers still had the cookie saved, but the incognito one dropped the cookie when it was closed. So when I re-opened the browsers, they still had their old CSRF cookie except the incognito browser.
I discovered this when I renamed the CSRF cookie and all the browsers stopped working. I had seen the cookie in Firebug and the Chrome dev tools, so I thought it was still being sent when it wasn't.
So, the end result is that the cookies work as I expected. All my confusion was due to the cached cookies still being sent. As far as I can tell now, the only difference with Incognito is that it clears out all the cookies when you close the last Incognito window.
Hopefully others will be reminded by this question that the cache could be getting in the way of your debugging. Checking for that early in this process could have saved me a lot of time.

chrome browser not sending 'If-None-Match' for xhr

I'm using an angular service to GET a resource via a rest api. The server sets the ETag header to some value and it also sets Cache-Control: no-cache in it's response.
This works as expected using Firefox, but when I access the same app using Chrome, it is not sending the If-None-Match. I've tried on current Chrome dev and stable channels on both a Mac and an Ubuntu box, and it was the same on both, while Firefox was adding the If-None-Match correctly.
Now, there are other non-xhr/static resources that are fetched conditionally and all those requests correctly get a 304 NOT MODIFIED response.
Is there anything I can do to get more information about why Chrome is not sending the If-None-Match header only for XHR requests?
If you're issuing an Ajax query in Chrome over HTTPS, any certificate errors, such as using a self-signed cert on your API server, prevent the response from being cached. This seems to be by design.
Evidently a Chrome defect existed but was fixed in Webkit and made it into Chromium / Chrome around 2010.
Another question recommends setting the If-Modified-Since and If-None-Match headers manually using jQuery's ifModified: true and cache: true options. Unfortunately this won't over-ride Chrome's intended behavior to not cache HTTPS responses from a server with a self signed certificate.
Testing on a server with a valid signed SSL certificate solved the issue for me; Chrome received 304's for text/html content as expected, using the default jQuery AJAX methods.

why ie8 CORS / XDomainRequest doesn't send cookie?

I've managed to make a CORS request on IE8 using XDomainRequest. However it seems the cookies are not sent on IE8. Is there any hack for that ? The request is made from buy.example.com to buy.api.example.com
There is no way except to include the authentication cookie value / token in the query string e.g. : buy.api.example.com/?sessionId=$sessionId&otherparameters=test and set your webservice to check the query string if cookies are not present.
There is another way. If you use SSL on the non-default https port, it will keep sending the cookies.
For example, if your URL is something like this https://example.com:8443/xxxx, then it will send the cookies.
I experience the same issue you have. My web app (internal web app) was working with https but in a non standard port and it just works fine. When I configure to use 443, it stops working because the cookies are not sent by XDomainRequest object.
I hope this will help

Resources