Is MVC AntiForgeryToken useless on public forms? - asp.net-mvc

I was told that there is no need to put the ValidateAntiForgery mechanism on our razor form because it's not behind authentication and is totally open to the public.
I thought I read somewhere that it should be used on all POSTs.
Which is correct?

There are a number of articles which can tell you when and where it is most appropriate to use the AntiForgeryToken. Here's a few:
http://www.devcurry.com/2013/01/what-is-antiforgerytoken-and-why-do-i.html
http://blog.stevensanderson.com/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/
http://peterkellner.net/2014/05/19/asp-net-mvc-forms-need-include-html-antiforgerytoken-security/
The last one is explicit, the author recommends that you should use the feature for all forms. It will be generally beneficial to your entire website, provided that you care about the identity of your users.
If your users have no session, and there is nothing to be gained from hijacking their ASP.NET cookie, then the anti forgery token is not particularly useful.

Related

Why doesn't WebSecurity.Logout *immediately* update IPrincipal.User to null user

First of all it's important to note that in my application if you log out your session is still valid and you don't just get redirected back to a login page, but stay on the same page.
With that said - whichever of these two ways I use to sign out in an MVC application
FormsAuthentication.SignOut()
WebSecurity.Logout()
the effect is the same and neither of the following properties changes to reflect the logout if I immediately access them :
User.Identity.Name
Thread.CurrentPrincipal.Identity
Now - If I do a Redirect, or just reload the page then obviously these properties are updated to a null user. They just don't immediately meaning that User.Identity.Name represents a user that just logged out.
This is a problem because I want to generate text of the form You are logged in as XXX after login/logout - and this may be in an AJAX situation where a redirect isn't possible.
I'm curious if there's any way to trigger the IPrincipal to reset itself after a logout (or login).
I assume people normally just Redirect() after a Logout() call so this is never an issue, but in an AJAX situation this is not always practical.
My current solution is to abstract the Identity in my own wrapper, and so once I'm logged out I can just update that. I'm just a little concerned that this could have some obscure side effects especially if somebody accesses IPrincipal directly adn not through the wrapper.
This is a core limitation of the ASP.NET event pipeline as it relates to forms authentication. This also makes it vulnerable to replay attacks, as described in KB article 900111. In that article, they reference one solution to use a membership provider that stores some server-side information about the logged on user.
Membership provider seems very similar to the approach you are thinking of taking, and I wonder if you should consider using one of the built-in membership providers, or writing your custom code as a membership provider. This should address some of the concern about people not understanding the approach and calling the IPrincipal directly.
Your "logout but stay on the same page" brings the issue a little more to the fore, but ultimately you're just uncovering the same fundamental replay issue that everyone has with ASP.NET (but not everyone solves it).
This related question may also be helpful.

What are security issues in asp.net mvc?

What are security issues in asp.net mvc?! and does MVC solved XSS and the others?!
As jfar says: watch out for SQL injection. :-)
It helps by allowing you to use some specific pieces, but you still have to use them in appropriate places.
Use the new default <%: that Html Encodes the output
Use the anti forgery request token
Use Any of the provided data access solutions. At the lowest possible level, use .Parameters to pass parameters
Pay attention to every bit of guidance
don't dismiss security advisory published, as the recent one affecting asp.net in general: is-asp-net-mvc-vulnerable-to-the-oracle-padding-attack
You still have to understand & question the security aspects.
The same as any other website. Just like any other language or framework Sql Injection and Request Forgery are only solved if you implement measures to prevent it. XSS is solved only if you don't need to accept HTML input and disable XSS validation.
Don't get soft thinking MS provided all the answers. It still takes a keen eye for flaws and a rigid application of counter measures to keep things secure.

What is it about the default ASP.NET MVC AccountController code that some hate?

I've read from a few individuals (Simone Chiaretta, Sebastien Lambla) that "you should remove the AccountController" from your ASP.NET MVC apps, but without much reason. I'm currently using it in one intranet site and am working on a second that will be considerably more widely used. What is wrong/bad about the default code that makes it undesirable?
Simone elaborates in comments. I have to disagree with him a little, though. Correctly implementing an authorization filter is not "easy." The first MVC previews got it wrong! In general, nothing which touches the area of security is "easy." However, the criticism of coupling is valid. Even if you use forms auth -- and you probably should use some off-the-shelf authentication if you're not a security expert -- the coupling is bad.

ASP.NET MVC Session State

Is there any way to tell if a visitor to a site is new, or just the same one over and over again, for the purpose of a hit counter?
Sessions don't really seem to exist in MVC, so I know I can't really use them...
Is there any way to tell if a visitor to a site is new, or just the same one over and over again, for the purpose of a hit counter?
There's not a 100% reliable way due to the stateless nature of the web but for the purposes of a counter, setting a cookie and checking whether it's there or not is adequate for the most cases.
Sessions don't really seem to exist in MVC, so I know I can't really use them...
This is not true. You can use Session in ASP.NET MVC too. Although, in general, you should avoid server-side state as much as possible when you don't need it to ease scalability.
You can use sessions in ASP.NET MVC, but as Mehrdad points out, storing this kind of information on the server is not the way to go about it--use JavaScript cookies instead. And let your clients do the "heavy lifting".
Quircksmode has a great article on using JavaScript cookies.

Securing an ASP.Net MVC Site

As a relative newcomer to both web and MVC, I am looking for a good summary of security best practices that I should implement.
The site will be public facing with "moderately sensitive data" (meaning we can't get sued, but probably wouldn't make many friends if the data got out!) and will have the following security steps taken:
a: Forms/membership authentication and authorization
b: Parameterized queries to prevent sql injection.
c: Automatic timeout with x min of inactivity
c: SSL for client to server encryption
What else do you recommend?
*Securing IIS and the network don't fall under my domain, so I'm more interested in the things I need to do to the software.
If you are using cookies to recognize users, be sure to use an arbitrary token (such as a GUID) to store on the client for identification. I've seen too many websites that store my email address or username in my cookie... just have to change it to another!
Write your software so that it can run under medium trust.
If you are new to web development you should be aware of cross site scripting (XSS). You can use Http.Encode helper method to protect against this in ASP.NET MVC.
Make sure you prevent out of order requests. Ensure client is authenticated before allowing to see sensitive data, or in some cases, make sure the client has come through the correct channel, before allowing a data manipulation. For example, only allow adding an item to your cart if the request came from the product details page. If you don't check, any one can mess around with the action. The URL would be like http://server/cart/add/XYZ123 and anyone could just tweak the 'id' parameter.
Here's another biggie to watch out for: CSRF
http://blog.codeville.net/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/
Take a look at this post by Phil Haack- one of the MS dev’s involved in the development.
Additionally take a look at Microsoft Anti-Cross Site Scripting Library to filter out all incoming parameters
Maybe you should choose methods that can be invoke from outside or not. For example be careful make a method like delete any tables like http://yourhost.com/edit/deletealltable.
Make sure you design your class and methods well. And give attributes [NonAction] for preventing public method being invoke.
Make sure you display data (especially sensitive) as you need with minimum fancy design and use client script as long as needed.
Remove any unused trash files like unused files in your solution folder.
Check and double check and validate any input control like textbox. I just can give something in the textbox to hack your system.
If you use mix between MVC and regular ASP.NET, please remove any dependency between them.
Be sure you cover the basics thoroughly, independently of ASP.NET. Make sure your DBMS has a separate user with the minimal required privileges (e.g., CRUD and executing sprocs from specified databases) set up to access the database from the web application. Parameterizing queries is an excellent idea, but ALWAYS SCRUB YOUR INPUT ANYWAY: it is not a complete defense against sql injection.
Keep your design clean and easy to understand. Document whatever you do clearly, especially on the database side. It would be very bad if all your good work were destroyed by two programmers months or years later--one who didn't realize, say, that the database user for the web application (now accessing a database on a different server) shouldn't have root privileges, and another who added a control that didn't cleanse input properly. There's only so much that can be done about this sort of thing, but designing for the possibility that fools will be maintaining your code isn't so that coders will think you're sweet--it's so that fools won't put you out of business.

Resources