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.
Related
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
TL;DR Why is it bad to put a CSRF Token in the GET request parameter?
Set up to the problem.
I have a search form on a SaaS app where the CSRF token is being injected for every form including the GET forms. This seems bad to me, but I can't articulate why and I'm being asked to.
All traffic is encrypted. So the GET parameters can't be wire sharked and scraped.
The worst scenario I can see here is some sort of social engineering where a malicious actor would ask someone to copy the URL and the user just handing it over without thinking it's dangerous.
Otherwise I can't really think of a scenario where a drive by hack is possible without the hacker going through the trouble of setting up a man in the middle scenario, and in which case they would probably be set up to do worse things without that CSRF Token.
what am I missing here?
Have a look at the OWASP CSRF Prevention Cheat Sheet and specially the section about Disclosure of Token in URL
What would be the security loophole if a logoff request is not validated with XSRF/CSRF token?
Don't think of Anti-CSRF tokens as a mechanism implemented on individual endpoints/requests. Ideally, such a mechanism is baked in as a critical part of the framework you're developing in.
An Anti-CSRF may seem redundant on a logout link, which is not what worries me here. What worries me is designing a system which allows, or rather, does not enforce Anti-CSRF mechanisms.
In this context, the CSRF may seem benign. What happens however, when the logout link is vulnerable to say, XSS? Suddenly the Anti-CSRF token is no longer there to protect you.
Always practice Defence in Depth, in that your security should be wrapped in layers, Anti-CSRF being one of them.
Could be combined with an OWASP A10, e.g. the attacker also provides a return URL that points somewhere bad, e.g. a fake "sign on again" page where he can capture your password.
I'm using the MEAN stack and want to make sure certain routes have an authenticated user. I've been reading up on JSON web tokens. This seems reasonable.
Before I invest anymore time into it, I want to ask if anyone else uses this and if there are any major flaws they've noticed thus far. And are there any other popular alternatives excluding passport?
JSON web tokens have several flaws which, when dealt with properly, can make the approach quite useful for performing authorization:
A client still needs to transmit user credentials to a authentication server, which means using secure transmissions is paramount
If sensitive information is placed into the token, this information should be encrypted by the client and sent across a secure transmission
Depending on how your constructing the token and who your sharing it with, tokens should have a limited lifetime, preventing others from destructuring the token since it's generation and potentially sending falsified data to servers
There are definitely other approaches to cookie-based authentication other than passport, but I'm not aware of any that are as well integrated and popularized, though I'm sure you might find something more efficient. There are other examples of cookie-based schemes that exists, which you could implement, for instance the auto-login scheme from SO.
If you want to invest the time to learn how to implement JWT, it would definitely be worth the effort. If your trying to asses whether you need to use JWT, a good rule of thumb is asking yourself whether you will have multiple authentication servers, will you need to authorize clients accross several different domains and whether you need the clients to have stateless/ephemeral authorization tokens.
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).