We have a ASP.NET MVC application. All the POST requests (form submits) have been protected from CSRF by using @Html.AntiForgeryToken
and ValidateAntiForgeryToken
attribute.
One of the action methods on a controller is a GET which returns a report to the user (a pdf file with data from database). The signature is:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetReport()
{
// get data from db
return GetReport();
}
Here are the steps I am following to test the CSRF against this operation:
Questions:
Can this be considered a CSRF attack?
If yes, how can it be mitigated? Since the action method is a GET request, how can I use MVC's CSRF approach (applying @Html.AntiForgeryToken
and ValidateAntiForgeryToken
on the action method).
HTML File:
<html>
<body>
<form action="https://<baseurl>/Analysis/GetReport">
<input type="submit" value="Submit request" />
</form>
</body>
</html>
CSRF GET RequestThe simplest CSRF attack is simply to trick a user into making a GET request to a specific URL. This can done by putting the URL into a deceptively named link. The link could be put in a blog comment (lots of WordPress exploits have used this technique), a post on a web forum, or in a phishing email.
A CSRF attack can either leverage a GET request or a POST request (though a POST request is more complicated and is thus uncommon). Either one needs to start with an attacker tricking a victim into loading or submitting the information to a web application.
You can protect users of your ASP.NET Core applications from CSRF attacks by using anti-forgery tokens. When you include anti-forgery tokens in your application, two different values are sent to the server with each POST. One of the values is sent as a browser cookie, and one is submitted as form data.
In short, what you've just described is not an example of an XSRF attack...
Both CSRF
and XSRF
are used to describe what's called a Cross Site Request Forgery
. It's where a malicious website takes advantage of your authenticated state on another website, to perform fraudulent cross-site requests.
Imagine that you're authenticated
on your bank's website, and that your banks website contains a form
to create new transactions, all pretty straight forward...
<!-- Your bank -->
<form action="/send_moneh" method="POST">
<input type="text" name="amount" />
<input type="text" name="accountNumber" />
<input type="submit" value="Send Money" />
</form>
The Malicious website
Now let's think of the Malicious website
you're also visiting, imagine that it also contains a form
, one that is hidden and the values of which are pre-populated...
<!-- Malicious website -->
<form action="http://yourbank.com/send_moneh" method="POST">
<input type="hidden" name="amount" value="100.00"/>
<input type="hidden" name="accountNumber" value="123456" />
</form>
When the form on the malicious website is submitted, an HTTP request
will be sent straight from you to your bank, and because you're authenticated on your bank's website, the transaction could be accepted.
Essentially, an attacker is using your own authentication against you by forging requests and using you as the messenger to deliver that request.
You use an anti-forgery token, this token
is a string containing a random value, the token is placed in your cookies
, in addition to your HTML forms.
When you receive a request, you validate that the form contains an anti-forgery token and that it matches the one stored in your cookies. A malicious site can not see the tokens your website sets on a client, and without this information, XSRF attacks are stopped in their tracks.
On your controller Action that will be handling the request, add the attribute [ValidateAntiForgeryToken]
, and in the HTML form add (@Html.AntiForgeryToken())
.
public class ExampleController : Controller
{
[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult Test(Foo fooModel)
{
// do your thing...
return this.View();
}
}
<form action="/Example/test" method="POST">
@Html.AntiForgeryToken()
<input type="text" name="bar" />
<input type="submit" value="Submit" />
</form>
That's it!
Anti-Forgery Tokens don't make a lot of sense when performing GET
requests, in fact, they don't make sense to have them anywhere that you're not modifying and persisting data, as any GET request will be returned to your user, not the attacker.
If you're Creating, Updating or Deleting data... make sure that you're using it then.
Ordinarily safe methods do not have to be protected against CSRF because they do not make changes to the application, and even if they're returning sensitive information this will be protected by the Same Origin Policy in the browser.
If your site is implemented as per standards, your GET requests should be safe and therefore do not need protection.
However, there is a specific case where a "Cross-Site DoS"* attack could be executed. Say your reporting page takes 10 seconds to execute, with 100% CPU usage on your database server, and 80% CPU usage on your web server.
Users of your website know never to go to https://<baseurl>/Analysis/GetReport
during office hours because it kills the server and gives other uses a bad user experience.
However, Chuck wants to knock your <baseurl>
website offline because he doesn't like you or your company.
On the busy forum he posts to often, http://forum.walkertexasranger.example.com
, he sets his signature to the following:
<img src="https://yoursite.example.org/Analysis/GetReport" width=0 height=0 />
He also knows that your company employees frequent the forum, often while also logged into yoursite.example.org
.
Every time one of Chuck's posts are read by your employees, authentication cookies are sent to https://yoursite.example.org/Analysis/GetReport
, so your site processes the request and generates the report, and your system goes offline because CPU is eaten by these constant requests.
So even though the request is a GET request and doesn't make any permanent changes to your system (aka "safe"), it is infact bringing down your system every time it is ran. Therefore, it would be better to protect this with some CSRF prevention methods. The easiest way would be to convert this so that the report can only be generated via a POST request and therefore the request can be validated via the AntiForgeryToken.
*XSDoS, or Cross-Site Denial of Service, is a phrase coined by me, so don't go Googling for it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With