SameSite Flag against CSRF - security

I was wondering if the SameSite flag on the session cookie was enough of a protection against CSRF attacks.
I see CSRF token solution everywhere, but I am not sure about the need to use a CSRF token if the cookie used for authentication is already protected by the SameSite flag (in Strict mode).
On top of that, if I understood it well, tho cookie would still be sent along with subdomain URLs like api.myapp.com which would be perfect for my needs.

This is somewhat opinionated, or at least depends on your target audience and risk appetite.
SameSite=strict is supported in almost all fairly recent browsers as seen here, but note the exception of IE11. Not many people use IE11 anymore, but for them it will not be good enough. Only you can answer whether that's good enough for your usecase, as of writing this, a significant amount of users would not be protected.
Also the general consensus seems to be that SameSite should only be used as defense in depth (eg. here or here in a similar question), but most of the concern is around Lax, and less about Strict. However, Strict is very user-unfriendly, in a real-world application you probably can't really use Strict, because that's very bad UX.
The usual arguments are around browser support (as above), GET requests changing state (only relevant to Lax), and some special cases still revolving around GET changing state.
So my take currently is that the reason SameSite=Strict is not good enough in general is the lack of full browser support (IE11), and a strong point against it is bad user experience. I can imagine circumstances where it is good enough. SameSite=Lax I think is only a defense in depth measure, because of the issues above, which probably don't affect your application now, but might in the future, and nobody will remember to think about SameSite settings.

Excellent answer from Gabor which explains the problem well. There is a way to solve this though, if you set up your code like an SPA, to work like this:
Requests for web content (such as navigation) do not require a cookie
The SameSite=strict cookie is only used in Ajax requests to get data
HOW IT WORKS
If your web app runs at https://mywebapp.com
Then issue the secure cookie as the result of calling an API at https://api.mywebapp.com
The cookie has a domain of .mywebapp.com and is SameSite + Cross Origin
OAUTH
For an OAuth back end for front end solution you would do this:
Host the API at https://api.mywebapp.com
When the web app receives an OAuth response, it sends the Authorization Code to the API
The API processes it, then issues a strongly encrypted cookie containing tokens

Related

Security Concerns regarding session cookies

I'm working with a website system in which session and remember cookies are flagged with Secure and HttpOnly. Now because of various reasons I need to access session and remember cookies in JavaScript (WebSocket Authentication with subdomain). Is it a reasonable thing to turn off the "HttpOnly" flag of both cookies regarding security?
I am aware that this opens the door for XSS attacks to get those cookies. But if I assure there is not XSS possible, do you think it is ok?
Greetings
Marvin
While the primary reason for httpOnly is XSS, there is a risk in having cookies without this flag.
The most obvious risk is that the statement that your application is not vulnerable to XSS sounds a little overly optimistic. If you have a very good reason to assume that, fine, but one reason I would think that is if the page is just all static (but why would it set cookies then). Another reason to accept this could be if XSS is an accepted risk, like for example the app is on an origin where it doesn't matter for some good reason. But these should be thought through and probably covered in a fairly detailed threat model. Any testing or scanning would (for me) be insufficient, any mitigation in the application's code I could also not accept for various reasons, if XSS really concerns me. Like for now it might really not have exploitable XSS. What about tomorrow? In 5 years, after 30 different people changed it..?
Also httpOnly is not only against XSS in its classic sense. For example you are probably using 3rd party components, javascript not controlled by you, but loaded by your application. By having httpOnly cookies, those client-side components will also not have access to cookies, but without httpOnly they will. Do you trust them that much? Maybe you should not - or maybe it's ok, it all depends on how you model threats and what you are willing to accept.

Why would one allow clients to switch off XSRF protection?

Some time ago I came across the option in one of the software I use at work, to turn off XSRF server-side protection by including a special HTTP header value on the client side. Therefore, I wonder:
How is this not a security vulnerability?
Why would you implement a security feature and allow clients to turn it off? Is there a use-case I am missing?
I am doubting my knowledge of XSRF protection at the moment and since we could not reach a consensus at work I decided to post my concerns here.
The product is Bamboo and they publicly report the option in https://confluence.atlassian.com/bamkb/rest-api-calls-fail-due-to-missing-xsrf-token-899447048.html#RESTAPIcallsfailduetoMissingXSRFToken-Workaround. I first mentioned this in an old answer here: https://stackoverflow.com/a/45090321/410939.
I can understand allowing the server to turn it off on a per API basis. However allowing the client to turn it off is a very bad idea... It's as good as not being there. The only reason I can think this is OK is for backwards compatibility. Maybe there is an older version of the client that relies on this way to mitigate CSRF, while newer clients use the new version, and switch off the older version (but one of them must be used).
I would turn the question around: Why would you implement security features and then ask users to turn them on? This is the opt-in model to security you will find everywhere, e.g. literally no one are forcing 2FA even though it is a huge security improvement.
If XSRF is session based and you run multiple tabs with the same application and you are forced to reauthenticate in one of them you will typically get a new XSRF token. Other tabs might then no longer pass the XSRF check with the risk of losing unsaved work. There could possibly be other similar scenarios.
There are sometimes trade offs between security and usability, in this case they make security default and let people who run into problems take an informed risk.
There are other ways to mitigate XSRF. So, if cookie is not an option (maybe the client doesn't support cookie), you might want to disable this cookie solution.
Some other ways to mitigate XSRF:
State Variable (Auth0 uses it) - The client will generate and pass with every request a cryptographically strong random nonce which the server will echo back along with its response allowing the client to validate the nonce. It's explained in Auth0 doc
Always check the referer header and accept requests only when referer is a trusted domain. If referer header is absent or a non-whitelisted domain, simply reject the request. When using SSL/TLS referrer is usually present. Landing pages (that is mostly informational and not containing login form or any secured content may be little relaxed ​and allow requests with missing referer header

Playback using saved session cookies

I did a small sample test and found that almost all web sites I tested suffer from the vulnerability where I can access restricted pages (ie pages that require logging in) even after I have logged out from the browser if I save the cookies while I am still logged on.
The test was fairly simple. I just replayed a web request in Fiddler after I had logged out from the browser. For example, with outlook.com, after logging out, I could replay the page that shows the address book and still get my contacts' email addresses.
May I know what the industry standard is regarding this as I have one customer who insists on fixing this vulnerability but not wanting to increase the hardware specs.
I'm not sure if there's an industry standard, but there are best practices. And the best practice is to clean the cookies, and cookie management.
You shouldn't have to worry about hardware on this either. It's a simple lookup to see if a value is valid. If it isn't, then the session state shouldn't get resurrected.
Again, I would use HttpOnly and a secure flag on the cookie. That way, it will limit replay attacks more. And when it comes to resurrecting sessions, make sure that session files are destroyed on the server, not just abandoned.
Abandoned sessions mean they can potentially be resurrected.
Hardware will generally not be an issue with this problem. If it is, then look at your solution, as there might be a better way.

No need for CSRF protection?

Quote:
The web has changed a lot since CSRF was a "big thing", and tactics
used with CSRF attacks are becoming outdated.
I personally don't protect against CSRF, mainly because I don't use
blatantly insecure methods of authentication.
Does he make any sense?
Please provide me with some arguments If I am correct, why this guy is being (stubborn?) or not thinking clearly as I am trying to make a point, but I am actually not hundred about to how to express it...
There is no sense in the quoted argument as-is, but presumably there is some other context we are missing.
It is unclear what form of authentication your colleague is proposing that would be 'not blatantly insecure', free from CSRF issues.
There are some possibilities, for example in a fully AJAX-driven app you might be passing in an auth token as an input parameter instead of relying on a session. In that case you wouldn't need an additional anti-CSRF measure as the auth token would already be a secret unavailable to attackers.
But CSRF in general has not gone away; browsers have not grown magic features to stop it happening. For the typical model of webapp that uses a browser-persistent authentication model (cookies, HTTP Authentication), you definitely still need to address it in some way.

Is this CSRF Countermeasure Effective?

Please let me know if the following approach to protecting against CSRF is effective.
Generate token and save on server
Send token to client via cookie
Javascript on client reads cookie and adds token to form before POSTing
Server compares token in form to saved token.
Can anyone see any vulnerabilities with sending the token via a cookie and reading it with JavaScript instead of putting it in the HTML?
The synchroniser token pattern relies on comparing random data known on the client with that posted in the form. Whilst you'd normally get the latter from a hidden form populated with the token at page render time, I can't see any obvious attack vectors by using JavaScript to populate it. The attacking site would need to be able to read the cookie to reconstruct the post request which it obviously can't do due to cross-domain cookie limitations.
You might find OWASP Top 10 for .NET developers part 5: Cross-Site Request Forgery (CSRF) useful (lot's of general CSRF info), particularly the section on cross-origin resource sharing.
If a persons traffic is being monitored the hacker will likely get the token also. But it sounds like a great plan. I would try to add a honeypot. Try to disguise the token as something else so It's not obvious. If it's triggered, send the bad user into the honeypot so they don't know they've been had.
My philosophy with security is simple and best illustrated with a story.
Two men are walking through the woods. They see a bear, freak out and start running. As the bear catches up to them and gaining one of them tells the other, "we'll never outrun this bear". the other guy responses, "I don't have to outrun the bear, I only have to outrun you!"
Anything you can add to your site to make it more secure the better off you'll be. Use a framework, validate all inputs (including all those in any public method) and you should be ok.
If your storing sensitive data I would setup a second sql server with no internet access. Have your back-end server constantly access your front-end server, pull and replace the sensitive data with bogus data. If your front-end server needs that sensitive data, which is likely, use a special method that uses a different database user (that has access) to pull it from the back-end server. Someone would have to completely own your machine to figure this out... and it would still take enough time that you should be able to pull the plug. Most likely, they'll pull all your data before realizing it's bogus... ha ha.
I wish I had a good solution on how to protect your customers better to avoid CSRF. But what you have looks like a pretty good deterrent.
This question over on Security Stack Exchange has some useful discussion on the subject.
I especially like #AviD's answer:
Don't.
-
Most common frameworks have this protection already built in (ASP.NET, Struts, Ruby I think), or there are existing libraries that have already been vetted. (e.g. OWASP's CSRFGuard).

Resources