I have a .Net MVC application. I use Asp.net Identity for login and roles.
Every controller I have is decorated with [Authorize]
I have not done anything else in the code to protect the application.
Is there anything Else that must be done in ordet to protect the site? And im not takling protection of the webserver. Only the website.
Thanks
Add MVC's anti-forgery support, this basically writes a unique value to an HTTP-only cookie and then the same value is written to the form. When the page is submitted, an error is raised if the cookie value doesn't match the form value.
It's important to note that the feature prevents cross site request forgeries.
How to use it:
Decorate every controller action used to post data with this: [ValidateAntiForgeryToken] and add the unique value to your form posting the data by adding the following to your form #Html.AntiForgeryToken()
Related
I have gone through many blog articles describing how to validate users in our web applications using [ValidateAntiForgeryToken] attribute. But this has limitations such as can be used only with HTTPPOST methods. My requirement is I have a MVC 5 application which returning sensitive data (Ex: bank statements) using HTTPGET methods. How to authorize/protect these action methods from anonymous users ?.
I want to write a token based authorization mechanism.
You are correct - the ValidateAntiForgeryToken mitigates against Cross-Site-REquest-Forgery (CSRF). It is specific to POST's, as it can correlate the a response issued by a server, and the HTML posted from a user. There is no concept of CSRF for GETs.
To protect GETS from anonymous users, use the [Authorize] attribute on any methods that you require users to be logged into the websites. If they are not, they will be redirected to the login section, as configured in your web.config.
I have a ASP.NET MVC website.
I don't really manage users, but I do a login to an external API and then I store a "ASPXFORMSAUTH" cookie.
It's a WCF service. In my controller, I call :
MyWcfServiceClient.Login()
In the AfterReceiveReply, I store the response of the service in a variable :
cookie = httpResponse.Headers[HttpResponseHeader.SetCookie];
Then In the controller, I get this cookie and store it using :
Response.Cookies.Add(cookie);
I'm a beginner with ASP.NET MVC, but can I use the [Authorize] attribute to allow the access to the controllers methods only if the request contains this cookie ? And [AllowAnonymous] on the methods before the API login.
EDIT :
So it should work just adding the [Authorize] attribute ?
I'm calling the controller method using ajax, and the value of Request.Headers["Cookie"] is .ASPXAUTH=1D415AF723......
But I get the ajax error callback...
Am I missing something ?
[Authorize] will allow access to authorized users only.
You can either put it at the top of the controller so it applies to all functions on the controller or in front of individual functions. its more powerful than that though as you can allow only specific users or roles. documentation here
The allow [AllowAnonymous] is used when you have added some sort of Authorize to the whole controller but want to allow access for all to a function on the controller. its not required if the controller doesn't have an authorize attribute on it. example here I think the default MVC account in visual studio uses this on the account controller for password rest and login.
I'm not fully sure since I haven't tried it before. But if you set the correct cookies (the default aspx auth cookie) the AuthorizeAttribute should prevent you from reaching the controller if you aren't authorized. Have you tried using the authorize attribute on a controller and logging in using your external API? Because it might just work out of the box.
Another option is to extend the default attribute by making your own. See the following articles for more information about this.
Article from John Galloway
Another question here on SO about extending the Authorize attribute
MSDN Article about the Authorize attribute
currently i'm working on ASP .NET MVC 4 application. We are using the provided [ValidateAntiForgeryToken] and the corresponding #Html.AntiForgeryToken() to generate the hidden field in our forms which are submitted using POST.
So far the mechanism seems to be working properly because if I don't provided the token as input hidden field to the target Action annotated with [ValidateAntiForgeryToken] an error is raised as expected.
However i found really strange that if i captured several generated token using Firebug or Chrome inspector, copy them into notepad and then go to a different page which also uses the AntiForgeryToken and basically replace the hidden field with any of the previous token generated, an error is not raised. I was expecting to always have a 1:1 relation (Page Hidden Field - ValidationAtServer], since if someone is able to obtain that value, will be able to forge any request to any form in the application which need the AntiForgeryToken
I was under the impression that once a token was generated it should not be possible to reuse the same token over an over, I see this a security flaw in the Framework itself.
If someone can provide more insight will be greatly appreciate it.
AntiForgeryToken is session base, so that each user has the same token but another user will have a different token. This descussion may be usefull for you: AntiForgeryToken changes per request
It's normal behaviour, because it's supposed that antiforgery token isn't compromised. If an atacker was able to compromise token, that means that atacker already has opportunity to compromise any other tokes, that would be generated. E.g. man in middle attacks.
So basically there is no need to gereate Antiforgery token per each request, and it will allow you to use already generated one for Ajax requests on current page.
Setup
In my MVC3 app, MembersController is decorated with an [Authorize] attribute.
MembersController has an Action called MyPage. Due to the Authorize attribute on the controller, MyPage can only be requested by authorized users.
Problem
When an unauthorized user tries to request /Members/MyPage they are correctly redirected to the Login page.
However, the ReturnUrl parameter is not passed into the login page, so when the user authenticates, they are taken to the default page (lets call it /Members/Home) instead of /Members/MyPage.
Question
Why?!
In another app, developed in MVC2, the returnUrl QS parameters is there and works as expected.
Other Issues:
The Autorize attribute is being ignored when decorating both controllers and actions.
Resolution:
Sections of web.config not properly updated between .NET 3.5 and .NET 4. See answers below.
#Marcind put me on the right track, #Darin Dimitrov's answer very instructive of the process involved.
Diagnosis
It seems that the issue was related to a web.config that I did not update properly when merging an existing Web Forms .NET 3.5 app to a .NET 4.0 app. I can't recall how I went about this.
Anyway, by comparing the web.config of my app with a new MVC 3 web.config, I was able to find the extra bits that should not have been there, left over from 3.5 days.
Resolution:
The issue was resolved by correcting the bits in the <authentication><forms> tag in the web.config, as well as the <membership> tag.
Other Issues Caused by this:
Another issue caused by this was the fact that if I decorated a controller with the Authorize attribute, it was ignored, so the controller tried to process info based on the current user, that obviously was null, so all manner of exceptions were fired.
It works for me. I created a new project using the ASP.NET MVC 3 RC2, default template, added a MembersController, decorated it with the [Authorize] attribute, run the application, requested /members/index, was redirected to /Account/LogOn?ReturnUrl=%2fmembers%2findex, logged in, was redirected to /members/index. There must be something else wrong with your code.
Here's how it works:
The [Authorize] attribute checks if the user is authenticated and if it is not it returns 401 status code.
The FormsAuthenticationModule which is part of ASP.NET and handles forms authentication intercepts the 401 status code and redirects to the login page by appending the ReturnUrl parameter to the request which points to the initial request.
The FormsAuthenticationModule module is not specific to ASP.NET MVC, this is standard ASP.NET stuff
I have a question about the returnUrl querystring parameter that is appended by ASP.Net when attempted to hit a page that requires authentication. In looking at Microsoft NerdDinner Sample's LogOn action (along with every other 'sample authentication code' I see on the 'net), it just has the ReturnUrl parameter declared in the action's signature and uses it directly in a Redirect() call. However, back in the WebForms days and using Membership Controls, we use to use the FormsAuthentication.GetReturnUrl() call. Besides returning the 'default url' if no url was specified in the querystring, it also does a few security checks (Cross App Redirect and 'IsDangerousUrl()'). Are those no longer a concern or are all the sample 'log on' actions I'm seeing all over the 'net just ignoring those issues?
I'm not sure about the samples that you've looked at, but it's entirely possibly to use Forms Authentication as is in MVC and benefit from the checks performed in The FormsAuthenticationModule processing (or using the FormsAuthentication class directly).
IIRC, the default MVC application in Visual Studio includes an adapter around forms authentication (AuthenticationService) which can be easily adapted to use the ReturnUrl querystring.
I imagine the samples in question have simply overlooked XSR attacks.