Skip to content

Instantly share code, notes, and snippets.

@oscarychen
Last active December 9, 2021 19:22
Show Gist options
  • Save oscarychen/ce189b2fef1f8ff7eac51a72fed34960 to your computer and use it in GitHub Desktop.
Save oscarychen/ce189b2fef1f8ff7eac51a72fed34960 to your computer and use it in GitHub Desktop.
cross site request forgery explained

Cross Site Request Forgery (CSRF)

Session Hijacking

Cookie sent over unencrypted HTTP connection

Mitigation

Use Secure attribute on cookie to prevent it from being sent over unencrypted connection: Set-Cookie: key=value; Secure

Use HttpOnly attribute to prevent access by JavaScript: Set-Cookie: key=value; Secure; HttpOnly

Do not rely on Path attribute for security, it can be bypassed using <iframe> with the path of the cookie: iframe.contentDocument.cookie. This is allowed by Same Origin Policy.

CSRF

Because of ambient authority, cookies are included to request to domains (even from unrelated website), it may force users to execute unwanted actions. It is effective even when the attacker can't read the HTTP response.

Referer header does not mitigate CSRF because of caching. Sites can opt out of sending the Referer header, some browser extensions might omit it for privacy reasons. It is good practice to:

Mitigation

Client side: set cookie attribute SameSite to Lax or Strict. Server side: use CSRF token on requests that rely on ambient authority (cookie-based authorization).

CSRF Token

  • Randomly generated string as CSRF token
  • Hashing of session id and a CSRF secret to create CSRF token

Case Study: Github third-party authentication CSRF vulnerability

This flow is valid, however in the implementation of the end points:

  • Github server did not check that this is a POST request and not HEAD request.
  • Github used the same URL for bring up authorization page and form submission.

The following outlines the coding for this Github authorization endpoint:

The vulnerability was that if an attacker sends a HEAD request instead POST, the request gets treated as GET and it does not trigger the web framework’s CSRF token checking mechanism. (Most web frameworks treats HEAD requests as GET and do not perform CSRF check on those).

To fix this vulnerability:

  • Use SameSite cookies in addition to CSRF token
  • Implement separate controller for GET/HEAD requests vs POST request, as well as catch-all case for handling wrong request types
  • Use separate URLs for authorization page and authorize endpoint

Based on Feross Aboukhadijeh's lectures (1, 2) on web security at Stanford University.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment