03. Cross-Site Request Forgery (XSRF)

Dated Nov 21, 2018; last modified on Mon, 05 Sep 2022

Cross-site Request Forgery (XSRF)

<img src="http://bank.com/transfer?from=from_ID&to=to_ID&value=1000">

Because the user is logged in and has a cookie, the victim site trusts the user’s browser.

The attacker gets user/browser to execute command on victim site, e.g. request a link, post a form. The command has permanent effects.

A frame can navigate its immediate children. Why is it designed such that it can’t navigate its children too?

Consider a website with a login frame, where the user inputs passwords. The attacker can put this website inside a frame and navigate to the login frame and steal passwords.

XSRF Defense

Classify URLs as public and non-public. Non-public URLs should contain an unpredictable user-specific secret. Even better, scope the secret to a session.

Same-Origin Policy (SOP)

Here’s a potential attack: https://attacker.com loads https://mail.google.com in an invisible page element and reads the user’s email.

//  Script on https://attacker.com....

var xhttp = new XMLHttpRequest();
xhttp.open("GET", "https://mail.google.com/...");
xhttp.send();

xhttp.onreadystatechange = function() {
    // Send response back to attacker.com
};

Scripts on different pages are allowed to access each other if and only if the pages they originate from share the same protocol, port and origin.

https://example.com/ has a different origin from https://www.example.com/. That said, websites tend to redirect the naked domain to the www domain for user convenience.

Note that SOP doesn’t prevent example.com loads an externally hosted script, e.g. <script src="https://third-party.com/lib/d3.js></script>. In this case, the origin of this script is still example.com because it was loaded on example.com

Problems with SOP

  • Subtly different policies for cookies, HTML5 storage, plugins
  • Ambiguities: different browsers, extensions, IP addresses…
  • Hostnames are not an accurate way to define trust boundaries, e.g. webhost.com/~alice vs webhost.com/~bob & login.example.com vs payments.example.com

I’ve mostly seen the example.com/~username pattern in universities, but that technique comes with security disclaimers. Web hosters that still intend to use the technique are advised to allow only static content.

Modern web hosters go the subdomain route, e.g. username.github.io, which complicates the login.example.com vs. payments.example.com. One mitigation is Mozilla’s Public Suffix List (PSL) .

The PSL has shortcomings, e.g. its opt-in model is default insecure; some providers don’t know about it; delays in reviewing PRs to the list and propagating the changes; entries growing stale and proving tricky to delete.

Solution: HTML5 postMessage

  • Message-passing API that allows security checks
  • Browser reports origin of message
  • JS code must enforce access control

References

  1. mod_userdir - Apache HTTP Server Version 2.4. httpd.apache.org . blog.hboeck.de . Accessed Aug 18, 2021.
  2. list/public_suffix_list.dat at master. github.com . publicsuffix.org . Accessed Aug 18, 2021.
  3. GitHub - sleevi/psl-problems. Ryan Sleevi. github.com . Accessed Aug 18, 2021.