Is it safe to build an API to provide CSRF one-time use token to avoid CSRF attack? Will this open a new vulnerability?
I have one more doubt regarding the traditional approach of including CSRF. I wonder that providing the csrf token in the form can be scraped and attack may be implemented by the attacker. Please correct me if my thought process in incorrect.
First of all you need to understand how a CSRF attack looks like. Someone can send you a link to http://malicious.com/whatever.html. You open this site and there will be an invisible form, that will send a POST request to http://example.com/account/1/delete. You will be logged into example.com on some other tab, so assuming the session is handled via a cookie, the cookie gets automatically attached and you execute a request you never intended to and are even unaware of.
We can mitigate the CSRF issue via different means, on of the being anti-CSRF tokens. The idea is that there is some kind of secret malicious.com will be unaware of and that can not easily be guessed. Please note, that in the CSRF scenario your means of attack are making people open some link. You have no access to the content of what they are seeing. You just send them a link and expect some requested to be executed with their access rights.
Related
I am working in a Razor pages project. In ASP.NET Core, #Html.AntiForgeryToken() is applied for preventing cross-site request forgery (XSRF/CSRF) attacks.
And I read an article about it:
https://www.red-gate.com/simple-talk/development/dotnet-development/anti-forgery-validation-asp-net-core/
This defense strategy works just as long as the controller’s code that handles the POST double-checks that it is receiving a hidden field named __RequestVerificationToken and a cookie with the same name.
By using postman, I can just simply copy the cookies value and the antiforgery token, and append it with the request so that I can post without visiting the page. And the cookies and token can be used repeatedly.
My question is, how can I do to prevent users/hackers calling the handlers/controllers without visiting the page and ensure that the token only can be used one time?
Do I have to write my own solutions for this? Or Microsoft already provided a solution?
The antiforgery token prevents csrf attacks. It does this by denying post requests that only contain the cookie. If the attacker has access to the antiforgery token then it is over. This is why the token must change when you log in. And it must be invalidated when you log out. It doesn’t necessarily need to change for each request.
https://owasp.org/www-community/Anti_CRSF_Tokens_ASP-NET
There are many strategies. Microsoft does not recommend you add the token to your cookies collection, but if you do, you must use HTTPS. As you know, cookies are exposed in each request. You can strengthen them with HttpOnly and Secure. But if you add HttpOnly, you can't read it yourself.
A better approach is to use headers because your header won't persist after the request is over.
As for Microsoft, here's a good resource: enter link description here
I've spent the last day or two pulling my hair out over this, so I thought I'd share the answer.
Problem: When trying to get an authentication cookie from the client side (using some http library or another), you get a 401 Unauthorised response. Even though you know the username and password are correct and you're doing it exactly how it's done in all the examples. Well my friend, your issue is that you expect things to make sense.
Turns out that if you have the require_valid_user set to true in the couch db config, and then don't include those credentials with an authentication request (even if the credentials you're authenticating are valid!) couch will reject it out of hand. So you've two options really,
Keep require_valid_user true and do your authentication on your own server where you can wack in the admin username and password as a part of the url (like so url = http://admin:password#url:5984). And then authenticate your credentials and pass back the ensuing cookie you get from that. (Make sure in subsequent requests straight from the client to the db you include withCredentials:true, so the browser sends the cookie with the request).
Say screw it and don't require a valid user with each request, and instead authenticate on the design doc and database security level only. I can't vouch for how secure this is, as I haven't done it.
Is it necessary to use CSRF Protection when the application relies on stateless authentication (using something like HMAC)?
Example:
We've got a single page app (otherwise we have to append the token on each link: ....
The user authenticates himself using POST /auth. On successful authentication the server will return some token.
The token will be stored via JavaScript in some variable inside the single page app.
This token will be used to access restricted URLs like /admin.
The token will always be transmitted inside HTTP Headers.
There's NO Http Session, and NO Cookies.
As far as I understand, there should(?!) be no possibility to use cross site attacks, because the browser won't store the token, and hence it cannot automatically send it to the server (that's what would happen when using Cookies/Session).
Am I missing something?
I found some information about CSRF + using no cookies for authentication:
https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/
"since you are not relying on cookies, you don't need to protect against cross site requests"
http://angular-tips.com/blog/2014/05/json-web-tokens-introduction/
"If we go down the cookies way, you really need to do CSRF to avoid cross site requests. That is something we can forget when using JWT as you will see."
(JWT = Json Web Token, a Token based authentication for stateless apps)
http://www.jamesward.com/2013/05/13/securing-single-page-apps-and-rest-services
"The easiest way to do authentication without risking CSRF vulnerabilities is to simply avoid using cookies to identify the user"
http://sitr.us/2011/08/26/cookies-are-bad-for-you.html
"The biggest problem with CSRF is that cookies provide absolutely no defense against this type of attack. If you are using cookie authentication you must also employ additional measures to protect against CSRF. The most basic precaution that you can take is to make sure that your application never performs any side-effects in response to GET requests."
There are plenty more pages, which state that you don't need any CSRF protection, if you don't use cookies for authentication. Of course you can still use cookies for everything else, but avoid storing anything like session_id inside it.
If you need to remember the user, there are 2 options:
localStorage: An in-browser key-value store. The stored data will be available even after the user closes the browser window. The data is not accessible by other websites, because every site gets its own storage.
sessionStorage: Also an in browser data store. The difference is: The data gets deleted when the user closes the browser window. But it is still useful, if your webapp consists of multiple pages. So you can do the following:
User logs in, then you store the token in sessionStorage
User clicks a link, which loads a new page (= a real link, and no javascript content-replace)
You can still access the token from sessionStorage
To logout, you can either manually delete the token from sessionStorage or wait for the user to close the browser window, which will clear all stored data.
(for both have a look here: http://www.w3schools.com/html/html5_webstorage.asp )
Are there any official standards for token auth?
JWT (Json Web Token): I think it's still a draft, but it's already used by many people and the concept looks simple and secure. (IETF: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-json-web-token-25 )
There are also libraries for lot's of framework available. Just google for it!
TL;DR
A JWT, if used without Cookies, negates the need for a CSRF token - BUT! by storing JWT in session/localStorage, your expose your JWT and user's identity if your site has an XSS vulnerability (fairly common). It is better to add a csrfToken key to the JWT and store the JWT in a cookie with secure and http-only attributes set.
Read this article with a good description for more info
https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage
You can make this CSRF protection stateless by including a xsrfToken JWT claim:
{
"iss": "http://galaxies.com",
"exp": 1300819380,
"scopes": ["explorer", "solar-harvester", "seller"],
"sub": "tom#andromeda.com",
"xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e"
}
So you will need to store the csrfToken in localStorage/sessionStorage as well as in the JWT itself (which is stored in a http-only and secure cookie). Then for csrf protection, verify that the csrf token in the JWT matches the submitted csrf-token header.
I am trying to get Twilio to work with my express/node.js installation. Twilio is making an incoming connection to my server, when it gets a text message. Then I am replying to this with a SMS response.
This works the first time. Then the second time, my server blocks Twilio because it says that it was a forged request.
Is there a proper way to get around this?
You should disable CSRF for that URL. See this question on how to do that: Disable csrf validation for some requests on Express
CSRF is a vulnerability that only pertains to requests that require session information in the form of a cookie (which is why CSRF is also sometimes called "session riding"). In short, CSRF is when a malicious site owner can use a <form> tag on a page they control to post a form to your site, causing an authenticated request to be sent to your server without the user's knowing. For instance, let's say Facebook has a /delete_user.php which deletes the current authenticated user. A CSRF attack on that URL will be in the form (no pun intended) of a <form action="http://facebook.com/delete_user.php"> tag on the malicious site owner's site, which gets submitted without the user's knowledge. A non-CSRF-safe implementation of /delete_user.php will see the user's auth cookie and delete the user -- much to the user's dismay.
Anyway, long story short, your Twilio handler does not require a user's browser cookie, and thus is not subject to CSRF attacks. Just disable CSRF checks for the Twilio callback URLs.
Can you please help me to resolve CSRF issue found during using asp.net 2.0.
Issue description :
[1 of 3] Cross-Site Request Forgery
Severity: Medium
Test Type: Application
Vulnerable URL: https://somesite/somepage.aspx
Remediation Tasks: Decline malicious requests
Reasoning:
The same request was sent twice in different sessions and the same response was received.
This shows that none of the parameters are dynamic (session identifiers are sent only in
cookies) and therefore that the application is vulnerable to this issue.
I would suggest reading up on CSRF in order to identify what you want to protect and why. Basically, the issue with CSRF is that an attacker can impersonate you and get back your data. You change this by passing in session information in the request, not just from the cookie. This makes your session secure from this type of attack. Here is a better explanation than I can give:
http://palisade.plynt.com/issues/2008Jun/cross-site-request-forgery/
Here is a two-part article on security issues (including CSRF) and how to address them:
http://palisade.plynt.com/issues/2009Dec/secure-coding-aspdotnet/
http://palisade.plynt.com/issues/2010Apr/secure-coding-aspdotnet-p2/
There is also a CodePlex project called AntiCSRF that makes it easy to fix these types of problems (although it hasn't been updated in a while):
http://anticsrf.codeplex.com/