Does Asp.Net Core prevent hidden inputs from being tampered? Is there signing of some sort handled by the middleware to prevent tampering? Does the __RequestVerificationToken take care of that?
ASP.NET Core implements antiforgery using ASP.NET Core Data Protection. Antiforgery middleware is added to the Dependency injection container when one of the following APIs is called in Startup.ConfigureServices: AddMvc, MapRazorPages, MapControllerRoute and MapBlazorHub.
When we add #Html.AntiForgeryToken in the <form> element, it will generate the hidden field to store the antiforgery token.
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
The token is unique and unpredictable. The server sends the token associated with the current user's identity to the client. The client sends back the token to the server for verification. If the server receives a token that doesn't match the authenticated user's identity, the request is rejected.
More detail information, please checking the Prevent Cross-Site Request Forgery (XSRF/CSRF) attacks in ASP.NET Core.
Related
I'm working on authentication part with Google OAuth2 API.
I'm using "server" flow, not "implicit".
When implementing step 1 for obtaining code guidelines recommend using the state parameter to ensure that in the end, the service provider will receive the response that correlates to the auth request he initiated.
See https://developers.google.com/identity/protocols/OpenIDConnect#createxsrftoken
I understand that there is a possibility that code can be stolen, and redirect_uri guessed.
But I don't understand why this is called anti-CSRF protection?
According to wiki CSRF attack "exploits the trust that a site has in a user's browser".
As I understand something sensitive should be kept in the browser to make CSRF attack possible. The most classic example - an authentication cookie.
But what is kept in the browser in relation to OpenID-connect code flow?
It is just two consequent redirects from service provider to identity provider and back. The code itself is passed on callback as a URL param.Browser's role is passive - to be redirected two times. Nothing is stored here.
So my question is what exactly kind of CSRF attack does state prevent? Can anyone give a detailed example? Or is it just misusing of term "CSRF" in google guidelines?
When using the authorization code flow in OAuth2, the user browses to the client application, which then redirects the browser to the authorization server to be logged in and get an access token.
302 https://auth.server/authorize?response_type=code&client_id=....
After you've signed in on the authorization server, it will redirect you back to the registered redirection URI with the issued code. The client application will then exchange the code for an access token and optionally go to a URL encoded in the state parameter.
Now, an attacker could trick you into clicking a link (from an email or something) like:
<a href="https://auth.server/authorize?response_type=code&client_id=...."
This would execute the same request to the authorization server. Once you logged in and the authorization server redirects you back to the client application, the client application has no way of knowing whether the incoming GET request with the authorization code was caused by a 302 redirect it initiated or by you clicking that hyperlink in the malicious email.
The client application can prevent this by sticking some entropy in the state parameter of the authorization request. Since the state parameter will be included as a query parameter on the final redirect back to the client application, the client application can check if the entropy matches what it kept locally (or in a secure HTTP only cookie) and know for sure that it initiated the authorization request, since there's no way an attacker can craft a URL with entropy in the state parameter that will match something the client application keeps.
The objective of CSRF is to dupe the user into performing an action (usually a destructive write action that the user wouldn't do under normal circumstances) in a website by clicking on a link sent by the attacker. An example of such an activity could be deletion of user's own account in the website. Assuming that the user is logged into the website, the requests originating from the user's browser are trusted by the website server which has no way to find out (without the CSRF token) that the user is actually duped into making that request.
In case of Google OAuth2 (Authorization code grant type), note that the initial request to the Google auth server contains the url that the user actually wants to visit after succesful authentication. An attacker can carefully contruct that url with some malicious intent and make the user use it.
The state token check enables the server ensure that the request is indeed originated from its own website and not from any other place. If the attacker creates the url with some random state token, the server wouldn't recognise that and reject the request.
If you have such doubts, best resource you must refer is the specification. For OAuth 2.0, this is RFC6749 . There is a dedicated section in the specification which discuss about Cross-Site Request Forgery
Cross-site request forgery (CSRF) is an exploit in which an attacker
causes the user-agent of a victim end-user to follow a malicious URI
(e.g., provided to the user-agent as a misleading link, image, or
redirection) to a trusting server (usually established via the
presence of a valid session cookie).
From the specification perspective, you must implement state handling mechanism into your application
The client MUST implement CSRF protection for its redirection URI.
This is typically accomplished by requiring any request sent to the
redirection URI endpoint to include a value that binds the request to
the user-agent's authenticated state (e.g., a hash of the session
cookie used to authenticate the user-agent). The client SHOULD
utilize the "state" request parameter to deliver this value to the
authorization server when making an authorization request.
And about a detailed explanation, directly from specifaciton
A CSRF attack against the client's redirection URI allows an attacker
to inject its own authorization code or access token, which can
result in the client using an access token associated with the
attacker's protected resources rather than the victim's
Injecting an authorisation code from attacker, then manipulating your application to behave in a manner attacker wants.
I am trying to implement jwt in cookies for auth on a single page application react front end which communicates with various node microservices running express.
I am doing this as it appears storing the jwt in sessionstorage makes the app vulnerable to XSS.
However, by using cookies, the apis are now vulnerable to csrf attacks.
Traditionally, csrf attacks are mitigated by creating a csrf token, storing it in a server session, then rendering it in a hidden form field.
Then, upon submitting the form, the value of the csrf token is checked against the server session value to check they match.
I cannot use this approach as:
- servers are stateless
- have no server side rendering.
So I am confused as to which csrf method I should employ.
I have read about double submit method, where you submit a csrf token on every ajax request, and have the same value stored in a cookie, then the server checks both for a match.
However, I cannot get the intial csrf token into the html in the first place as there is no server side rendering.
What is the best practice for achieving jwt in cookies with csrf protection in a stateless architecture with no server side rendering?
Simply don't store the JWT token in a cookie
CSRF attacks are possible because browsers will send cookies with HTTP requests, even if they are initiated by a script running on a 3rd party site. Thus evilsite.com might send a DELETE http://yoursite.com/items/1 request to your web service. This endpoint requires you to be logged in, but because the browser will send any cookies stored for yoursite.com, if authentication is cookie based then evilsite.com can piggy back on your authentication method and call authenticated methods that your user didn't intend to call on their behalf.
However, authentication doesn't have to be cookie based. If you are creating a client-rendered JavaScript app, then it is simple to send the authentication token as an HTTP header rather than in a cookie. If you do this then it is impossible for evilsite.com to make use of your token (they can only use tokens stored in cookies), and you never have the problem in the first place.
We are using C# MVC with Entity Framework and custom authentication implementing OWIN to make authentiation available by a custom user database.
Users login and authenticate themself by username and password by a standard login form.
To fit common security messurements OWIN regenerates the ".AspNet.ApplicationCookie" on each login and logout, I also force the "SessionIDManager" to regenerate a new Session ID (saved in .AspNet.ApplicationCookie) on each authentication change.
We use QUALYS to test the application for well known attack scenarios such as XSS, Session Hijacking etc. One imortant technic is to issue and validate Antiforgey Token which will be placed inside the form field AND inside a cookie stored on the client. As I unterstood these do not have to match since they are encrypted and get verified after decrypted on serverside on POST request (with ValidateAntiForgeryToken Attribute).
As mentioned above we use QUALYS to cover possible vulnerability scenarios. The report mentioned a security issue with the "__RequestVerifiationToken" which is set in the cookie and will not be regenerated until it gets invalidated by time. I reproduced this by tracking the traffic with Fiddler.
So the Token are there, get verified and I can log in, log out, chagne password and so on.
My question is, is there a build in possibility to reissue a __RequestVerifiationToken for the cookie?
When using the HtmlHelper #Html.AntiForgeryToken() it regerenates a new token for the hidden form field on each reload, but the cookie value keeps the same over time. I need to regerenate the cookie __RequestVerifiationToken value as well, at least on login / logout actions.
A side question is why internet explorer (Edge) requests result in a long time request when I manipulate the hidden form field content, firefox instead gets the error that a AntiForgery Erros occured?
The standard SSO routine involves actively redirecting a user from the SP to the IDP and back. While this mechanism has several great advantages, the disadvantage is that the redirect may confuse users. ("Hey I was just on azure.com and now I am live.com huh?").
I would like to support a scenario in which a username/password login form is included in the website of the SP. In this specific scenario, I am both owner of the SP and IDP and have full control over its implementation. How would one achieve such a situation? I can imagine the following approach:
<form action="https://idp.contoso.com/login" method="post">
<input type="hidden" name="issuer" value="sp.contoso.com">
Username: <input type="text" name="username"><br>
Password: <input type="text" name="password"><br>
<input type="submit" value="Submit">
</form>
Include above form in the website of the SP.
IDP accepts POST, validates credentials and creates a SAML-response
IDP returns website with an automatic submitting form that POST's the SAML-response to the issuer's SAML2 endpoint url (e.g. https://sp.contoso.com/saml)
SP accepts POST, validates SAML response and builds a user session based on SP specific criteria
Is this a viable solution? If so, ss this in any way supported by standards compliant products like WSO2 Identity Server? If not, what is a proper way to authenticate an user against an IDP while using a login form from the SP?
The entire idea with deferring login to an external authority is to not have to deal with the login interface. In many cases the Idp uses smart cards, one time SMS codes or similar so it's not only a simple username/password combo to login in.
If you control both the SP and the Idp and want to avoid the redirect to the Idp, I think it's probably better to create an API on the Idp side that lets the SP supply a username/password and get an authentication result back directly. That result could be in the form of a SAML Assertion, but also something custom.
I just tried out same type of scenario using WSO2IS, It contains some thing called request path autenticators which validates the user credentials that comes in the login request. Yes.. As an example, if you take SAML2 SSO scenario, SP can send SAML2 Auth request using POST binding to IDP. In the same request SP can send the end user's credentials that is retrieved from the login page of SP application. Then you would not see the login page in IDP and credential are retrieved from auth request and validates with IDP's user store. If success SAML2 response is generated. I have write some blog about it with sample Serivice provider application and WSO2IS, I hope it may be helpful for you. Please see it from here
I am trying to implement a user friendly anti CSRF mechanism.
Currently my application program sets a cookie and session variable with the anti-csrf token and sends it to user.
Whenever the user makes an unsafe request(POST,DELETE,PUT) javascript reads the cookie and adds the token to the form which is sent via an ajax request
On server the form value is compared with session contained value.
Problem is my application will be open in multiple tabs and it it highly probable the the token will expire on server.
Is it a good practice to get new csrf tokens from a server file like
get-csrf-token.php
Because anyways the attacker cannot read the response from cross site requests(considering jsonp and cors is disabled)
EDIT:
I plan to keep single CSRF token valid per hour per session and the web applications will re-request new tokens after an hour
Is there anything wrong with this approach?
You only need one CSRF token per user session. As any attacker cannot read the token due to the Same Origin Policy, you do not need to refresh the token until the next session is active. This will mean there will be no problems with your application being open in multiple tabs.
Your approach is an implementation of the Synchronizer Token Pattern CSRF protection mechanism, which is the OWASP recommended approach. As JavaScript is used to add the value to the request, you can't mark your cookie as httpOnly. This would have prevented any XSS vulnerabilities from allowing an attacker to grab your cookie value. However, if you do have any XSS vulnerabilities, these are slightly more serious than CSRF ones and should be addressed immediately anyway as there are other attack vectors once an XSS flaw is found.
See this post for some pros and cons of some CSRF mechanisms: Why is it common to put CSRF prevention tokens in cookies?
In my project, I use cookies for managing authentication of users, and use session for generating the CSRF token.
When generating the form, it should be included in hidden field. For ex:
<form method="post" action="/paymoney">
<input type="hidden" name="csrf" value="csrf value" />
...
</form>
When user makes an request, the server should authenticate the request first (via cookie). After that, the server get the correct user session and verify the CSRF token.
Note that, you should care about the time out of CSRF token. The more expired time of this token, the less efficiency you can get. But if the expired time is too short, it cause a trouble that some ajax call can not work although the authentication of user is still valid.