What is CSRF Protection really for?

2019-02-16 10:04发布

问题:

I've been hearing about CSRF a long time ago, and the thing I hear most of the time is:

Protecting against CSRF attacks is important so that someone doesn't submit your form automatically (using a bot or something)

Well, that isn't 100% true, is it?

I've been doing web scraping for about 3 years, and it is pretty straightforward to make a request, parse the csrftokenmiddleware field and POST it along with the other fields.

So, what is it really for?

回答1:

Imagine an e-banking web application at banking.example.com with the following form to submit a transaction:

<form action="/transaction" method="post">
    <input type="text" name="beneficiary"/>
    <input type="text" name="amount"/>
    <input type="submit" value="Pay"/>
</form>

An attacker could now set up a website at hacker.net with the following:

<form action="https://banking.example.com/transaction" method="post" style="visibility:hidden">
    <input type="text" name="beneficiary" value="John Doe, Account No. 34-236326-1"/>
    <input type="text" name="amount" value="1000000"/>
    <input type="submit" value="Pay"/>
</form>
<script>
    document.forms[0].submit();
</script>

The attacker would then trick victims into visiting hacker.net, which will cause the victims' browsers to send a POST request to the e-banking application, making a large transaction to the hacker. This works because the victim's browser happily sends the session cookie along with the forged POST request to the e-banking application. If the form would have been protected by a CSRF token, then the attacker could not have caused the victim's browser to send a valid POST request and thus the attack would not be possible.

This type of attack is called a Cross-Site Request Forgery (CSRF) attack.

Incidently, CSRF attacks are also the reason why people give the advice of never ever visiting other websites while being logged into an e-banking or other critical web application.

CSRF tokens do not protect a web form being automatically submitted by regular authorized users as themselves. To protect from that, you'd use a CAPTCHA.



回答2:

Yes, you can scrape the form and get the CSRF prevention token. But you can't submit the form without scraping the site, and you can't get a token from someone else and then submit the form -- it's linked to a session. That's what CSRF protection really prevents, someone tricking a user into submitting a form.


A more general description of CSRFs, originally posted in response to Django's comments framework and CSRF:

A CSRF is an attack where someone without permission to access a resource tricks someone who does have permission into accessing it.

So, for example, CSRF protection could prevent someone from tricking a user into posting a comment with a spam or malware link in it. Alternatively, the request they trick the user into making could be malformed, made to crash your webserver, or include code meant to slip through the validation process and cause damage to your database or compromise your site in other ways.

So without CSRF protection someone could, theoretically, trick a logged in user into submitting a comment they didn't actually write.

With CSRF protection, Django will detect that it wasn't real data submitted through the actual form on your site, and will reject it.



回答3:

It's a protection for a different type of scenario. Sometimes the attacker is able to inject either javascript, either iframes or img src-s to a page of yours, in a place that any logged in user can access. When user accesses the page (let's say a page with comments, and one comment requests a link by the attackers posting), that request is being made by the loggedin user's browser, altogether with his cookies. CSRF basically protects this kind of triggered submits (simple client-side submits). Of course, any attacker can request the page, parse it for the token and create the request with the token, but can not do this on beside of a logged in user.



回答4:

You won't be able to

to make a request, parse the csrftokenmiddleware field and POST it along with the other fields.

because JS on a different domain won't be able to fetch and use data from your domain to construct requests if your server is configured properly.

Read about CORS.