4

From microsoft docs:

CSRF vulnerabilities are fundamentally a problem with the web app, not the end user.

And indeed, the typical solution (CSRF tokens) is a server-side solution rather than client-side solution.

That may be a philosophical question, but... I'm not sure if I understand this approach. For me, CSRF vulnerability is when the browser makes an unauthorized request; and thus this is a problem with the browser. So, client-side measures should be taken, not server side. It is the browser which must stop making unauthorized requests.

CSRF tokens don't seem to solve this fundamental problem. Rogue sites may still use the browser to make malicious requests. Only that particular type of malicious requests is solved, but others are not. One possibility that comes to my mind: a malicious site may make the browser send a lot of repeated requests to another site, effectively making the browser participate in a DDOS attack.

So instead, to solve this issue... why not make the browsers more secure? One simplest example: By default, disallow cross-site requests at all? This seems to make sense from the theoretical POV: why should different domains (this should mean: different parties) want to talk to themselves through the user?

2
  • 2
    Using your example at the end, how would you be able to include images, scripts, stylesheets etc. from other sources without allowing "cross-site" requests? Also, how does the browser know what is "authorized"? May 17, 2018 at 17:55
  • "It is the browser which must stop making unauthorized requests." By even launching a Web server, you are authorized the requests. By using a Web browser, the user has accepted the semantics of Web browsing, including that.
    – curiousguy
    Jun 28, 2018 at 21:10

3 Answers 3

3

Theoretically, you are right: the web could have been designed in such a way that browsers could detect and prevent these attacks. However, it was not designed that way, and there is no trivial fix that a browser can apply that doesn't break large number of existing websites.

One simplest example: By default, disallow cross-site requests at all?

A "cross-site request", in the context of CSRF, could be as simple as "an <img> tag referencing an image hosted on another domain". Preventing such requests would break so many websites that the browser would simply be considered broken by all its users.

It is the browser which must stop making unauthorized requests.

The request is only "unauthorised" in the sense that a particular user didn't request it. This, on the face of it, is a more promising approach: allow the request to be made, but don't let it be authenticated as the action of any particular user.

The problem here is that the vast majority of authentication used by web applications is not actually visible to the browser as authentication at all; at most, the browser knows that the server has requested that one or more opaque strings ("cookies") be returned to it on the next request.

So, browsers would need to stop sending all cookies in requests which are "cross-site", in the sense of CSRF - when requesting images and other assets for use in an HTML page served from a different domain; when submitting forms targetting a different domain; etc.

why should different domains (this should mean: different parties) want to talk to themselves through the user?

One obvious use case is the tracking systems used by analytics and advertising services - you might argue we'd be better off if browsers did just break them, but since the world's most popular web browser right now is developed by a company that makes a large portion of its revenue from such services, this is unlikely to happen.

Sometimes, communicating between services in the browser actually enhances the user's privacy - if the only communication that can happen is on the server, both servers have to know and discuss the user's identity.

If the web had evolved with these security considerations in mind, the safe uses of CSRF-like behaviour would be implemented by other means; but even if new protocols and APIs are invented now, it is very hard to change the default behaviour of browsers without breaking a large amount of existing content.

As such, features to protect against it, however standardised, will always be opt in, so require some work by the developer of the application, to say "I'm not relying on feature X, so please disable it so it can't be abused". Things like Content Security Policy headers, and the HttpOnly and SameSite cookie options, are such opt-ins. Things like CSRF tokens in forms are ways of not relying on the user to have an up to date browser that implements all the necessary protections.

2

You are correct in a sense that the problem is with the browser rather than the web app, and nowadays SameSite cookies can be used to fix this. Ultimately though the problem isn't that simple, because some cross-site requests are legitimate, like clicking on a link.

If StackExchange had SameSite set to strict and a user came to the site by clicking a link from a Google search, the cookie wouldn't be sent because it was a cross-site request and the page wouldn't show the user as logged in, even if they had logged in earlier. This is unintuitive and bad UX. This can be solved by setting SameSite to lax, but then CSRF may still be possible if the web app isn't compliant with RFC 7231 section 4.2.1, and unfortunately I've seen many web apps with non-idempotent GET requests.

Blocking all cross-site requests is simply not feasible with the way things currently work. It prevents too many legitimate uses such as CDNs, embedding images, ads, etc. This page currently makes requests to these domains:

adservice.google.com
ajax.googleapis.com
cdn.sstatic.net
pixel.quantserve.com
qa.sockets.stackexchange.com
sb.scorecardresearch.com
securepubads.g.doubleclick.net
secure.quantserve.com
security.stackexchange.com
www.google-analytics.com
www.googletagservices.com
www.gravatar.com
3
  • "SameSite set to strict and a user came to the site by clicking a link" ...and if you jump to the main URL of a website with a "mobile browser" (one with a mobile UA string), you are redirected to the special mobile page on the same site, and you are then authenticated. And then there is the difference between links from security.stackexchange.com to crypto.stackexchange.com (same "registrable" domain) and to stackoverflow.com (unrelated domain). Very counter intuitive for a system with a unified identity. (Same linking from Google to YT.)
    – curiousguy
    Jun 28, 2018 at 20:55
  • If "strict" is implemented, browser need to indicate in the URL bar when the page was requested from an origin of a different registrable domain!
    – curiousguy
    Jun 28, 2018 at 21:11
  • "This is unintuitive and bad UX.": That's not a good argument, since "intuition" is built from experience, and if it was the case that browsers wouldn't send cookies in third party-requests, that would be the norm and hence not counter-intuitive. The root of the problem really lies in the fact that Cookies are both used for authentication and passed in third-party requests, which is simply inconsistent. May 17 at 21:05
1

CSRF, along with most attacks, is possible because an application doesn't properly validate inputs. Inputs must always be validated regardless of the source.

If you do validate your inputs, you don't need to rely on users or even Google, Mozilla,... to ensure security.

On the other hand, even if Google and Mozilla came up with a secure version of their browsers which absolutely prevents any kind of CSRF, users of your application would still be vulnerable if they don't update their browsers.

If you think everybody updates their browsers, you are wrong. Lots of people still use 5-10 years old browsers, and the same goes for other important applications. With the advent of IoT, this issue has become even worse.

Bottom line: if you want your users to be secure, is it more convenient to add some countermeasures to your application or to ask Google and Mozilla to immediately shut down the root cause of CSRFs and force all your users to update to this new browser version?

What's more, shutting down the root cause of CSRF is not so easy. As @IMSoP correctly pointed out, this would basically break the current analytics and ads industries. Also see: https://stackoverflow.com/questions/37559773/why-do-browsers-allow-csrf.

Again, if you want your users to be secure, is it more convenient to add a few lines of code to your app OR to disrupt a multi-million/billion dollar industry?

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .