0

I'm trying to understand CSRF tokens and one thing isn't making sense to me.

For a web API, you can provide a CSRF token just once, on authentication, and expect the client to remember that token (using local storage or some other means) throughout the course of its use of the application. It can be submitted with every request so that we know those requests are genuine, as an attacker cannot know the token without the submitting the user's credentials.

In the browser/HTML, though, the recommendation is to include the CSRF token in a hidden form field. In that scenario, though, the attacker's script can submit a GET request to get the form, grab the token from the response, and use it to submit a POST of the form (and potentially any other form they so desire). Sure, they have to do two things instead of one, but it's still entirely possible as far as I can tell.

When this scenario is mentioned, the replies seem to be something like "you have to rely on the same-origin policy to prevent this." But isn't the entire premise of using these CSRF tokens that we can't rely on the proper implementation of the same-origin policy in user agents? If we're relying on the same-origin policy, why bother with CSRF tokens in hidden form fields in the first place?

curiousguy
  • 5,028
  • 3
  • 25
  • 27
Kate Jo
  • 3
  • 2

2 Answers2

4

You seem to misunderstand both the same-origin policy and CSRF.

The same-origin policy is crucial for any kind of browser security. It makes sure that client-side scripts from one website cannot access information from another site. Without this, we'd have much bigger problems than CSRF: Any website could read our e-mails with our webmail account (while we're logged in), make transactions with our PayPal account, buy products with our shop accounts etc.

So we have to rely on the same-origin policy. If it breaks down, we essentially lose all security, including the CSRF protection.

However, the same-origin policy alone isn't enough. An HTML form may very well point to a different site, so I could prepare a form on my site, use your site as the target and then wait for one of your users to submit the data. If you only check the session ID of the submitter and then accept the request, I've successfully performed a CSRF attack.

That's why we need anti-CSRF tokens: To prevent other websites from “forging” requests, we can, for example, establish a shared secret with the user and only accept form submissions which include this secret. Since the same-origin policy prevents other websites from reading this token, it's no longer possible for them to create a valid form. They don't know what to put into the token parameter.

In the context of web APIs, CSRF is generally not an issue. Automated clients usually send specific requests to specific URLs, so there's no way for an external website to jump in and trigger malicious requests. Maybe you're confusing CSRF tokens with authentication tokens? Those are two entirely different things.

Fleche
  • 4,024
  • 1
  • 17
  • 20
  • What I was missing was that there was no restriction on submitting POST requests across domains via forms; I was under the impression that CSRF was done through cross-domain AJAX requests. So is the same-origin policy primarily implemented within browsers? – Kate Jo Feb 13 '15 at 20:31
4

You seem confused the concepts of Same Origin Policy, CSRF, and what can be done with HTML forms; and you aren't alone! The Web a complex mix of many technologies developed without sufficient security evaluation, with subtly different policies.

An interactive website can provide different content to different users, using tokens sent by the browser and sometimes the IP address. The Same Origin Policy is the foundation of the security of websites with access control, but it is neither simple, nor well understood, nor easy to explain, nor easy to reason about.

The Same Origin Policy is very unclean, with many edge cases, but the basic idea is simple: a website (a "origin" as defined by its Fully Qualified Domain Name, and TCP port if custom port is used, and URL scheme) can only read data from the same origin. In the modern Web, a website usually contains programs (as JavaScript) so it is really an active agent. Nearly each Web page incorporates many pieces of JS; all the JS programs from all the Web pages of a single site are assumed to be mutually trusted.

The Same Origin Policy doesn't restrict the inclusion of elements from another origin, such a images, in a page; but the site won't be able to "see" the images (but it can detect its size, an exception to the simplified policy as stated above).

The Web model, since the old times (remember the NCSA Mosaic browser?), does not restrict cross-site requests:

  • Simply including an IMG element will cause a GET request; if the browser has any HTTP cookies in it's current "cookie jar", the request will be made with these cookies (also, HTTP login/password authentication will be sent if the browser has stored some - but who used HTTP authentication today?). "Cookies" (not just HTTP cookies) can be used to prove a level of authorisation. The HTTP GET request will be "authenticated" by the browser. (Also, the request will come from the IP address of the user, and IP addresses are something used for access control.)

  • An HTML FORM element can any domain for its submit URL. It can use either the GET or the POST method.

Web pages can also be framesets with frames from different origins, or use inline frames (IFRAME element). In both cases, the outer page cannot mess with the content of inner page: it can't read it, it can't modify its elements. But the outer page can be hostile and misrepresent the inner page, by providing a ridiculously small area, by hiding borders, confusing the user about what is what, thus creating security issues because the user only see one origin in the address bar. Ad-hoc defenses were designed after the fact (as usual, lack of complete security analysis for web technologies).

There are exceptions to the policy as stated above: a Web page can import scripts (JS) and style sheets (CSS) from other domains. These HTTP objects must have the appropriate MIME types, or the browser must block the use of the resource (not doing so would be a violation of the SOP). The scripts will run in the security context of the importing website, but they were retrieved by the web browser with the cookies of the domain hosting the script. This means that you cannot include a secret in a script or a CSS (protected by origin).

And HTTP cookies don't even follow a simple "Same Origin" model. HTTP cookies have their own special, potentially unsafe rules for setting cookies on other origins: cookies can be scoped by "origin" or domain (like *.example.com), and be "secure" or not, "HTTP-only" or not... (Lack of proper security analysis at design time, again.)

Since NCSA Mosaic, the Web changed much, with JS scripting having a huge impact. A script can interact with any HTML element of the page, notably it can "click" on links and submit HTML FORM elements. A FORM can cause a POST request to an arbitrary site. This is not a violation of the Same Origin Policy as the script has no way to read the returned data. (OTOH, this is often a surprise for many persons who have incorrect intuition about the Web.) The POST request will be made using the usual user cookies, this implies that if the user is authenticated on the website, a webpage with just a POST form and some JavaScript can make a request in his name.

HTTP cookies carry auth token linked to a domain, not a particular window; the web browser uses it for any request on the domain (it is called "ambient authority"). By default (that is unless some obscure Google Chromium command line option is used) any other website could try to abuse this authority. CSRF tokens are a defense against that.

CSRF are not a defense against a broken web browser, such as the Android Web Browser (not to be confused with Google Chrome!) before version 4.4 (see CVE-2014-6041).

About authority by cookies, see also https://www.rfc-editor.org/rfc/rfc6265#section-8.2

8.2. Ambient Authority

A server that uses cookies to authenticate users can suffer security vulnerabilities because some user agents let remote parties issue HTTP requests from the user agent (e.g., via HTTP redirects or HTML forms). When issuing those requests, user agents attach cookies even if the remote party does not know the contents of the cookies, potentially letting the remote party exercise authority at an unwary server.

Although this security concern goes by a number of names (e.g.,
cross-site request forgery, confused deputy), the issue stems from
cookies being a form of ambient authority. Cookies encourage server
operators to separate designation (in the form of URLs) from
authorization (in the form of cookies). Consequently, the user agent might supply the authorization for a resource designated by the
attacker, possibly causing the server or its clients to undertake
actions designated by the attacker as though they were authorized by
the user.

curiousguy
  • 5,028
  • 3
  • 25
  • 27