Understanding CSRF

2019-01-13 20:24发布

问题:

I don't understand how using a 'challenge token' would add any sort of prevention: what value should compared with what?

From OWASP:

In general, developers need only generate this token once for the current session. After initial generation of this token, the value is stored in the session and is utilized for each subsequent request until the session expires.

If I understand the process correctly, this is what happens.

I log in at http://example.com and a session/cookie is created containing this random token. Then, every form includes a hidden input also containing this random value from the session which is compared with the session/cookie upon form submission.

But what does that accomplish? Aren't you just taking session data, putting it in the page, and then comparing it with the exact same session data? Seems like circular reasoning. These articles keep talking about following the "same-origin policy" but that makes no sense, because all CSRF attacks ARE of the same origin as the user, just tricking the user into doing actions he/she didn't intend.

Is there any alternative other than appending the token to every single URL as a query string? Seems very ugly and impractical, and makes bookmarking harder for the user.

回答1:

The attacker has no way to get the token. Therefore the requests won't take any effect.

I recommend this post from Gnucitizen. It has a pretty decent CSRF explanation: http://www.gnucitizen.org/blog/csrf-demystified/



回答2:

You need to keep researching this topic for your self, but I guess that's why you are posting to SO :). CSRF is a very serious and widespread vulnerability type that all web app developers should be aware of.

First of all, there is more than one same origin policy. But the most important part is that a script being hosted from http://whatever.com cannot READ data from http://victom.com, but it can SEND data via POST and GET. If the request only contains information that is known to the attacker, then the attacker can forge a request on the victom's browser and send it anywhere. Here are 3 XSRF exploits that are building requests that do not contain a random token.

If the site contains a random token then you have to use XSS to bypass the protection that the Same Origin Policy provides. Using XSS you can force javascript to "originate" from another domain, then it can use XmlHttpRequest to read the token and forge the request. Here is an exploit I wrote that does just that.



回答3:

CSRF Explained with an analogy - Example:

Imagine you're opening your front door using a key - your key. nobody else has your key. You open the door – but before you go inside, your neighbour calls you over from across the road and you both have a very amicable conversation about the weather or perhaps President Trump’s latest 3.45 am tweets etc. While you are having this conversation, unbeknownst to you, somebody else sees you outside, and decides to impersonate you by wearing your same clothes and hair style and decides to go into your own house pretending to be you!

Nobody inside your house notices anything different - your wife is like, ‘oh crud*, he’s home’.

The impersonator helps himself to all of your money, and perhaps plays some Xbox on the way out and nobody is any wiser.

CSRF basically relies on the fact that you opened the door to your house and then left it open, allowing someone else to simply walk in and pretend to be you.

What is the way to solve this problem?

When you first open the door to your house, you are given a paper with a long and very random number written on it by your door man:

"ASDFLJWERLI2343234"

Now, if you wanna get into your own house, you have to present that piece of paper to the door man to get in.

So now when the impersonator tries to get into your house, the door man asks:

"What is the random number written on the paper?"

If the impersonator doesn't have the correct number, then he won't get in. Either that or he must guess the random number correctly - which is a very difficult task. What's worse is that the random number is valid for only 20 minutes (e.g). So know the impersonator must guess correctly, and not only that, he has only 20 minutes to get the right answer. That's way too much effort! So he gives up.

Granted, the analogy is a little strained, but I hope it is helpful to you.

**crud = (Create, Read, Updated Delete)



回答4:

Is there any alternative other than appending the token to every single URL as a query string? Seems very ugly and impractical, and makes bookmarking harder for the user.

There is no reason to append the token to every URL on your site, as long as you ensure that all GET requests on your site are read-only. If you are using a GET request to modify data on the server, you'd have to protect it using a CSRF token.

The funny part with CSRF is that while an attacker can make any http request to your site, he cannot read back the response.

If you have GET urls without a random token, the attacker will be able to make a request, but he won't be able to read back the response. If that url changed some state on the server, the attackers job is done. But if just generated some html, the attacker has gained nothing and you have lost nothing.