Skip to content

Latest commit

 

History

History
139 lines (91 loc) · 5.69 KB

File metadata and controls

139 lines (91 loc) · 5.69 KB

Cross-site request forgery (CSRF) 🎭

Trick a user into performing an action they don't intend to perform. This could be:

  • changing their account email to allow for password reset,
  • changing content or users on the site, or
  • transfering funds to the attacker.

Key factors

For CSRF to be possible:

  1. There must be an action a user can be tricked into performing unintentionally,
  2. Only session cookies are used to validate the user's permission to perform the action; and
  3. The action must have predictable parameters (e.g. no CSRF tokens involved).

This HTTP request is vulnerable to CSRF:

POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
Cookie: session=yvthwsztyeQkAPzeQ5gHgTvlyxHfsAfE

email=wiener@normal-user.com

The attacker can create a page with the following HTML page to cause the user to change their email address when a victim visits it:

<html>
    <body>
        <form action="https://vulnerable-website.com/email/change" method="POST">
            <input type="hidden" name="email" value="pwned@evil-user.net" />
        </form>
        <script>
            document.forms[0].submit();
        </script>
    </body>
</html>

For the above to work, the victim must be logged in to the vulnerable website and the session cookie is not using the SameSite attribute.

⚠️ CSRF attacks can also occur when HTTP basic auth or cerfiticate auth is used by a site.

CSRF SameSite defense

An attribute set on session cookies that can have one of two values:

  • Strict: the cookie is only sent with same-site requests.
  • Lax: the cookie is sent with same-site requests and top-level GET navigations (e.g. user clicking a link).

The risk with Lax is that some sites will allow sensitive actions to be performed via GET requests, even if not explicitly coded that way.

Attacks

CSRF are delivery is similar to XSS and depends on the HTTP verb used to perform the action:

  • POST: create an HTML form with the action and params and induce the victim to visit the page.
  • GET: create an image element with the malicious action as a src and have the victim visit the page:
<img src="https://vulnerable-website.com/email/change?email=pwned@evil-user.net">

There are several different ways to bypass CSRF defenses, depending on the site:

  • CSRF not validated for GET requests.
  • CSRF not validated if token is missing.
  • CSRF not tied to user session and only checked for validity. In this case, the attacker can use their own CSRF token in the attack.
  • CSRF tied to a non-session cookie. Relies on the attacker being able to set a cookie on the victim's browser.
  • CSRF is set in the cookie ("double submit cookie pattern") and the attacker can set the cookie on the victim's request.

Referer based validation

Some sites attempt to prevent CSRF by checking the Referer header. However this header can be spoofed or crafted in such a way to bypass the check.

# Bypass check where referer header must start with the vulnerable site domain
http://vulnerable-website.com.attacker-website.com/csrf-attack

# Bypass check were referer must appear in the header value
http://attacker-website.com/csrf-attack?vulnerable-website.com

💡 Modern browsers now strip query parameters from the Referer header. You can override this by setting the Referrer-Policy: unsafe-url header on your request.

XSS vs CSRF

Both attacks involve causing the victim to unintentionally perform an action:

  • 'XSS': caues the victim to execute malicious JavaScript on the vulnerable site.
  • 'CSRF': causes the victim to perform an action on the vulnerable site through visiting a malicious page.

CSRF is generally harder to exploit because most sites implement CSRF defenses and the attacks usually only apply to a subset of user actions.

CSRF are also only "one-way" in that they cause a user to submit a request, but the attacker cannot see the response directly. With XSS the attacker can see the response and can use it to further their attack.

XSS and CSRF tokens

Reflected XSS can be mitigated by CSRF tokens since they add a unique value to each request. But, CSRF tokens are not always validated for all requests and can be bypassed.

Stored XSS are not prevented by CSRF as they trigger when the user visits the page, which will include a valid CSRF token generated by the site.

Prevent

  • Use CSRF tokens with high entropy that are tied to the user's session.
  • Use SameSite cookies.
  • Provide additional forms of verification on sensitve requests.

CSRF tokens

Unique, high-entropy random value submitted with a user's request. The server validates the token to ensure the request is not a CSRF attack. Additional context specific values (e.g. timestamp + salt) can be used to generate the token, which makes it harder to guess.

These tokens should be transmitted either as:

  • a hidden field that appears before any user controllable content to prevent the attacker from inserting their own token into the request; or
  • a header value since browsers prevent injecting custom headers on cross-domain requests.
<input type="hidden" name="csrf-token" value="CIwNZNlR4XbisJF39I8yWnWX9wX4WFoz" />

Tokens should not be transmitted as GET request parameters because:

  • it will be logged in client/server-side logging,
  • it is visible in the user's address bar, and
  • it can be transmitted in the Referer header to third parties.

Tools

References