Are CSRF Tokens automatically applied in AspNetCore 3.+ Controllers? - asp.net-mvc

I've read that CSRF Tokens are automatically validated in Razor Pages but does this also apply to Controllers or do I still have to use the #Html.AntiForgeryToken() TagHelper in my view and the [ValidateAntiForgeryToken] attribute on my controller method?
If so, I've read on Andrew Locks Blog that I could add a Filter to do the same but this was before NetCore 3.+.
Is this implementation in my Startup.cs correct?
services.AddControllers()
.AddMvcOptions(options => {
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});

No you do not need to use the #Html.AntiForgeryToken() because when you use the <form> tag helper it will insert the anti-forgery token for you (if the method attribute is "post" and the action is not an external hyperlink).
https://learn.microsoft.com/en-us/aspnet/core/security/anti-request-forgery?view=aspnetcore-3.1#aspnet-core-antiforgery-configuration
In ASP.NET Core 2.0 or later, the FormTagHelper injects antiforgery tokens into HTML form elements.
And:
The automatic generation of antiforgery tokens for HTML form elements happens when the tag contains the method="post" attribute and either of the following are true:
The action attribute is empty (action="").
The action attribute isn't supplied ().
Also:
We recommend use of AutoValidateAntiforgeryToken broadly for non-API scenarios. This ensures POST actions are protected by default. The alternative is to ignore antiforgery tokens by default, unless ValidateAntiForgeryToken is applied to individual action methods.

Related

ValidateAntiForgeryToken doesn't do the only thing it is suppose to do

I am implementing AntiForgeryToken feature to my asp.net core mvc project. As usual, I have included #Html.AntiForgeryToken() inside the form tags so it looks like this:
<form method="post" action="mycontroller/myaction">
#Html.AntiForgeryToken()
<input type="text" name="myInput"/>
<button type="submit">Submit</button>
</form>
and as you can imagine, here is the myaction action in my mycontroller controller:
[HttpPost]
[Route("somepath")]
[ValidateAntiForgeryToken]
public IActionResult myaction()
{
//some code here
}
Now the problem is, I NEVER GET ANY ERROR!!
I removed the #Html.AntiForgeryToken from the view and the [ValidateAntiForgeryToken] doesn't do a thing! the post action works just fine.
Here are two things I have tried that might give you a clue:
I tried both [ValidateAntiForgeryToken] and [ValidateAntiForgeryToken()], no difference!
Someone said that the attribute only works in authorized controllers or actions. Tried this in my controller that has the [Authorize] tag.
PS: I have not added any code in my Startup.cs like services.AddMvc(...). Could it be something about that??
Please help.
ValidateAntiForgeryToken is used to prevent cross-site request forgery attacks.
Antiforgery middleware has been added to the Dependency injection container when services.AddMvc() is called,and The FormTagHelper has injected antiforgery tokens into HTML form elements already.You don't need to call #Html.AntiForgeryToken()
For more details ,you could check this document.
In and MVC app (which you have there), request verification using an anti forgery token is opt in. You opt in by decorating the controller action with the [ValidateAntiForgeryToken] attribute. If you omit the attribute, the request is not subject to verification. In each of the scenarios you described, there is no reason for an error. The only time you are likely to see an error (in the shape of a 400 HTTP status code) in an MVC app is if you decorate the action with the [ValidateAntiForgeryToken] attribute but the cookie or token are not included as part of the request payload.
In Razor Pages, all POST requests are verified by default. You can opt out of request verification, in which case you can opt in on a page by page basis by adding the attribute to the PageModel class (not the handler method) The anti-forgery token is generated by the form tag helper when the method is set to POST in both Razor Pages and MVC views.
Sometimes, you might want to post without a form (using AJAX most commonly) in which case you need to generate the anti-forgery token in the view so that you can include it within the post request payload. The Html.AntiforgeryToken helper (which is a legacy from older versions of MVC) provides a convenient way to do that.
I've written in detail about this process here: https://www.learnrazorpages.com/security/request-verification

MVC.NET how to secure submitting forms after edit

When I want to submit a form to save an edited record, I should pass its Id to controller. Then a client (or attacker) may change some information (e.g. this Id) on the form that I don't want to be changed. I can create a hashed hidden field to check that read-only fields have not been changed and verify it when it is posted to controller.
Is there any other good practice for this issue?
Thanks
You can encode data you want to protect with server side algorithm, that way that view receives encoded data only. When user passed the form to controller you decode data and check for validity. Also remember to implement not only client side validation, but also server side validation for your model.
AntiForgeryToken: A great feature in ASP.NET MVC is the AntiForgeryToken. This Generates a hidden form field (anti-forgery token) that is validated when the form is submitted. The anti-forgery token can be used to help protect your application against cross-site request forgery
.cshtml Code
#using (Html.BeginForm("Index", "Home"))
{
#Html.AntiForgeryToken()
}
Controller Code
[ValidateAntiForgeryToken()]
[HttpPost]
public ActionResult Index()
{
//Your Code
return View();
}

What are filters in asp.net mvc

What are the filters in asp.net mvc, can any one explain clearly.
How to create a custom filters in asp.net mvc 4
[Authorize]
Public ActionResults Index()
{
return View()
};
In ASP.NET MVC, controllers define action methods that usually have a one-to-one relationship with possible user interactions, such as clicking a link or submitting a form. For example, when the user clicks a link, a request is routed to the designated controller, and the corresponding action method is called.
Sometimes you want to perform logic either before an action method is called or after an action method runs. To support this, ASP.NET MVC provides action filters. Action filters are custom attributes that provide a declarative means to add pre-action and post-action behavior to controller action methods.
Check Filters-and-Attributes-in-ASPNET-MVC
The filter attribute has the Order property which can be used to manage the orders. The order needs to be the order the business process to be followed. For example if HandleError attribute is given higher order than the Authorize attribute then even an unauthorized users will be getting application errors. It would be better saying "Please Login".

how to add a csrf token to a fake symfony form

I have a form called ObjectCollectionOuterForm which extends from sfForm. ObjectCollectionOuterForm is the main form of an embedded form, each embedded form has disabled its csrf with: $this->disableLocalCSRFProtection(), so now my form protection depends on the outer form but since it´s not a sfFormDoctrine dependent it has a field called _csrf_token but with no value inside. How can I generate it?
The CSRF protection is handled by sfForm class, it has nothing to do with sfFormDoctrine. The secret should get generated for you, but if you have problems you can pass it as a third argument to your form's constructor:
$form = new ObjectCollectionOuterForm($defaults, $options, $CSRFSecret);

Anti-forgery token is not reused

As I read the anti-forgery system that ASP.NET MVC implements generate a token that can be reused across the same session, my question is why then this token changes every time I generate a new form in my app? I am talking about the hidden input field, not about the cookie value.
Thanks.
No. the token is not reused.
Every page refresh will generate a new value in Form input (and Cookie as well, in case it is invalid or not exist). upon submission, the server will try to match the form value against the Cookie value.
Taken from Professional ASP.NET.MVC 3 book
Token Verifi cation ASP.NET MVC includes a nice way of preventing CSRF
attacks, and it works on the principle of verifying that the user who
submitted the data to your site did so willingly. The simplest way to
do this is to embed a hidden input into each form request that
contains a unique value. You can do this with the HTML Helpers by
including this in every form:
<form action=”/account/register”
> method=”post”> <#Html.AntiForgeryToken()> … </form>
Html.AntiForgeryToken will output an encrypted value as a hidden
input: This value
will match another value that is stored as a session cookie in the
user’s browser. When the form is posted, these values will be matched
using an ActionFilter:
[ValidateAntiforgeryToken] public ActionResult
> Register(…)

Resources