4

I'm surely missing something in the picture of how CSRF attacks and protections are working.

My understanding in a form-submit scenery is the protection rely on a unpredictable token, someway is assumed the attacker can't get the token, why?

If the attacker is good enough to make me submit a form (as mentioned by OWASP) what would prevent him from getting the token before submitting?

There's a limit on javascript size/syntax that can be injected or is just the assumption I'm using a modern browser with Same-Origin Policy, what am I not seeing?

edit

My doubt, if I'm an attacker and I can inject javascript in the user form, why I can't get (using ajax) the form with the secret token, extract and inject the token in the form to be submitted?

edit 2

Forgive me for being pedantic but I'm trying to use CSRF protection on a php server and I may setup it wrong if I don't understand.

Regarding the OWASP's POST scenario example with submit onload, evil.com is the site the attacked user is visiting right? It will fire a post submit to the targetSite.com, the javasript onload in the example is simple but it could have been complex using a get of the form with the secret token before submitting, is that right?

If this is the case, is just the Same-Origin-Policy protecting the attacked user?

D.W.
  • 98,420
  • 30
  • 267
  • 572
Alex
  • 151
  • 1
  • 5
  • I'm assuming you meant cross-site-request-forgery (CSRF), not CRSF (??). – Mike Ounsworth Jul 31 '15 at 16:52
  • 1
    @MikeOunsworth yes, thanks for edit it, I always typo CSRF – Alex Jul 31 '15 at 16:53
  • What research have you done? This is explained in dozens of places on how CSRF protection works. We expect you to do a significant amount of research before asking, and to show us what research you've done in the question. Sharing your research helps others in a similar situation, and helps us give you better answers. Have you read The Tangled Web? Have you searched thoroughly on this site? Also, please don't use "stuff. edit: more stuff". Just edit your question to be what it should have been from the start, and leave out the "edit:"s. – D.W. Jul 31 '15 at 19:59
  • See also http://security.stackexchange.com/q/25900/971, http://security.stackexchange.com/q/94996/971, http://security.stackexchange.com/q/43522/971, http://security.stackexchange.com/q/35924/971, http://security.stackexchange.com/q/86759/971, http://security.stackexchange.com/q/8264/971. – D.W. Jul 31 '15 at 20:08
  • Thanks @D.W. for your links and for pointing out my wrongs, I been reading in the past about the argument and again a lot today, I wasn't comfortable blindly using existing implementations and landed here exhausted I just posted after a very light search here, my wrong. – Alex Jul 31 '15 at 21:14
  • @D.W. while the answer you pointed out as duplicate is what I was hoping for, a simple "yes can't be done because of the Same-Origin-Policy" I think *Anonymous*'s answer add value to it. Thanks everyone for the effort, I understood some point better. – Alex Jul 31 '15 at 21:18

4 Answers4

5

If the attacker is good enough to make me submit a form (as mentioned by OWASP) what would prevent him from getting the token before submitting?

The only skill an attacker needs to have is the ability to write HTML and javascript and know what the request they are trying to attack looks like. These are all things that are easily accessible and are not secret in any way.

So your assumption that the ability to create a form somehow means they can predict random tokens is incorrect.

Each token is unique to an authenticated user and unless there is another vulnerability, there isn't a way to figure out what that token is.

Based on how your question is phrased I'm not sure you have a full grasp of how CSRF works. This isn't meant as an insult - it can be a difficult concept to grasp initially.

My suggestion would be to create a form that is vulnerable to this type of attack and then execute an attack against it. This is an excellent way to get a thorough understanding of how this attack works. Once you do this - I suspect you will understand this answer better.

Cheers!

UPDATE:

It seems like you might be assuming that CSRF and XSS are the same thing. Just to clarify - in a site with only a CSRF vulnerability, a malicious user cannot insert any javascript. So there is no way to use javascript to get the token. If a site has an XSS vulnerability - then there is no need to execute a CSRF attack, because it would be much easier to simply inject javascript that does what you want. Also - a CSRF is a "one way" attack, meaning you can send a request as someone, but you can't read the result. Does this make sense?

UPDATE 2:

regarding your comment:

Thanks for clarifying, I was looking at the OWASP page linked in the question, section POST scenario, the submit onload, isn't that a CSRF attack with javascript injection?

Ahh - I see your confusion. No, the javascript they are showing is on the site controlled by the attacker. So if the attacker controls evil.com the javascript would be on there, and it is simply used to launch an HTTP request to targetSite.com using a users existing session. CSRF is an attack on existing sessions that takes place at the HTTP request level. It might use javascript to launch this attack, but the attack is still an HTTP request.

Abe Miessler
  • 8,155
  • 10
  • 44
  • 72
  • No offence taken, I'm not CSRF expert and that's why I'm here asking. `So your assumption that the ability to create a form somehow means they can predict random tokens is incorrect`, you don't say why. – Alex Jul 31 '15 at 17:42
  • The paragraph before that explains why. – Abe Miessler Jul 31 '15 at 17:44
  • I don't see it, an attacker with javascript skill can get the token before submitting, can't because of Same-Origin-Policy or there are other reason? – Alex Jul 31 '15 at 17:49
  • Check my update - I think it might clarify a few things – Abe Miessler Jul 31 '15 at 17:51
  • Thanks for clarifying, I was looking at the OWASP page linked in the question, section *POST scenario*, the submit *onload*, isn't that a CSRF attack with javascript injection? – Alex Jul 31 '15 at 18:00
  • It's a CSRF attack with javascript. There's not necessarily any "injection" because the html document containing the form and the onload attribute doesn't have to be *on* the target site. – John Morahan Jul 31 '15 at 18:07
  • I think I see why you are confused. See update #2 – Abe Miessler Jul 31 '15 at 18:08
  • Please see *edit 2* in the question – Alex Jul 31 '15 at 18:26
2

I'm not an expert on CSRF (please comment if I have misconceptions), but from wikipedia:

Under the [same-origin policy], a web browser permits scripts contained in a first web page to access data in a second web page, but only if both web pages have the same origin. An origin is defined as a combination of URI scheme, hostname, and port number.

A simplified example is: lets say you have 3 tabs open in your browser which have loaded scripts from three sources: 1.aaa.com, 2.aaa.com and www.bbb.com. Your browser, under the same-origin policy (SOP), will allow the scripts from 1.aaa.com and 2.aaa.com to read and write data each other's data. This is how facebook stays logged in across all your tabs (even on non-facebook pages, cause the embedded facebook scripts are dynamically loaded from *.facebook.com, and therefore have the same origin).

However, a browser that implements SOP will prevent scripts from www.bbb.com from being able to read data meant for the *.aaa.com scripts. This prevents a malicious script from seeing that random token that another script has been assigned. SOP does not block writes, so a malicious script can still send requests claiming to be another script, but unless it can guess the random token, that request will be ignored.

I agree that the system is a little mind-warpy, but it does work.

Mike Ounsworth
  • 57,707
  • 21
  • 150
  • 207
2

Without the token check, the attacker wouldn't even need to inject javascript.

For example, they create a form on https://evil.example/ that submits to an action at https://target.example/. Instead of injecting javascript on the target site, they can just place it directly on the site they control and trick you to visit that. The POST request will still include target.example's cookies. If it doesn't check for a token, then the form submission will be accepted just as if it had come directly from target.example itself.

However, if there is a token check, evil.example can't obtain the token because of same-origin policy. So they would need an additional vulnerability on the target site. For example XSS would allow the attacker to retrieve the token via AJAX.

John Morahan
  • 1,971
  • 2
  • 10
  • 9
2

The reason that sites are able to impersonate users performing actions is because browsers will willingly submit a HTML <form> to any other domain specified using the action attribute without concern the origins being the same or any other restrictions provided by the target domain. The original domain has no way to read what was received by the user or whether the request was successful. The original domain is simply sending the user off to the target domain to perform one specific action.*

The reason that this CSRF attack does not work when using a token is because the user also sends cookies relevant to the target domain with each request. The original domain has no way to read these because cookies do not work cross-domain except in certain cases where the target domain is showing relation to the other. Therefore, it should not be able to reliably predict what the token on the target domain is.

All the target domain needs to do is check that the value sent in the request matches the cookie sent.

* original domain - domain that forces a user to send the POST/GET request
* target domain - domain receives the request and "owns" the CSRF token cookie.


The original domain has no way to view the token because any request for it would fail:

  1. If the original domain requested it using PHP, the target domain should show a totally irrelevant cookie that is meant for that specific "user" (the original domain server, not the attacked user).
  2. If the original domain tries to read the cookie, the browser should only show the cookies relevant to the original domain, eliminating the possibility of reading a cookie from another domain.
  3. If the original domain requested a page using JavaScript, the browser should reject it because cross-domain ajax requests are not allowed (assuming the target domain does not explicitly allow it).
Anonymous
  • 590
  • 2
  • 7
  • 13
  • Thanks, but if I'm not mistaken not all implementations are using cookies (as the example in the OWASP page) does that mean are insecure? Is the PHP SESSION ID cookie that does the trick? – Alex Jul 31 '15 at 18:56
  • @Alex Not at all. Which other implementation are you referring to? – Anonymous Jul 31 '15 at 18:58
  • Any cookie would work. A server can store the value indirectly in a cookie using the PHP SESSION ID if it wants to. – Anonymous Jul 31 '15 at 19:00