CSRF Vulnerability Prevention

Cross-Site Request Forgery (CSRF) is a common vulnerability in web applications that allows an attacker to induce users to perform actions that they do not intend to perform. In this section, we will discuss several measures that can be implemented to protect web applications from CSRF vulnerabilities.

CSRF Tokens

CSRF tokens are the most effective defense against CSRF attacks. A CSRF token is a unique, secret, and unpredictable value generated by the server-side application and included in HTTP requests. When a user submits a form or makes a state-changing request, the server verifies that the token in the request matches the token it generated for that user's session. If the tokens do not match, the request is rejected.

Key characteristics of effective CSRF tokens:

  • Unpredictable: Tokens should be cryptographically random to prevent attackers from guessing them.

  • Bound to the user's session: Each token should be associated with a specific user session and invalidated after use or expiration.

  • Included in all state-changing requests: Tokens should be present in all requests that modify data or state on the server (e.g., POST, PUT, DELETE requests).

CSRF tokens can be implemented in various ways, such as hidden fields in HTML forms, custom HTTP headers, or as part of the URL (though this is less secure as tokens can be leaked).

The SameSite cookie attribute is a modern defense mechanism that helps mitigate CSRF attacks by controlling when cookies are sent with cross-site requests. As discussed in previous sections, the SameSite attribute can be set to Strict, Lax, or None.

  • SameSite=Strict: Cookies are sent only with same-site requests. This provides strong protection against CSRF, as cookies are not sent with any cross-site requests, even when navigating to the origin URL.

  • SameSite=Lax: Cookies are sent with same-site requests and with top-level cross-site GET requests (e.g., navigation). They are not sent with POST requests or requests embedded in img, script, iframe, etc. This provides a good balance between security and user experience.

  • SameSite=None: Cookies are sent with all requests, both same-site and cross-site. This value requires the Secure attribute, meaning the cookie must only be sent over HTTPS. While SameSite=None allows cross-site requests, it still provides some protection by requiring Secure and making explicit the intent to allow cross-site usage.

It is recommended to set the SameSite attribute to Lax or Strict for session cookies and other sensitive cookies to prevent them from being sent with unauthorized cross-site requests.

Referer Header Check

The Referer (sic) header contains the URL of the page that linked to the current page. Web applications can check this header to ensure that requests originate from a trusted domain. If a request's Referer header does not match the expected origin, the request can be blocked.

However, Referer header checks are not a foolproof defense:

  • Referer leakage: The Referer header can be suppressed or manipulated by browser settings, extensions, or network configurations.

  • Subdomain issues: If the application has multiple subdomains, improper implementation of Referer checks can lead to bypasses if an attacker can control a subdomain.

  • SameSite bypasses: As discussed in previous sections, SameSite cookie bypasses can sometimes render Referer checks ineffective.

Therefore, Referer header checks should be used as a supplementary defense rather than a primary one.

Custom HTTP Headers

Requiring a custom HTTP header for state-changing requests can also provide protection against CSRF. Modern browsers typically only allow JavaScript to add custom headers to same-origin requests. Therefore, an attacker cannot forge a cross-origin request with a custom header, making it an effective defense.

For example, a server might require an X-Requested-With: XMLHttpRequest header for all AJAX requests. Since an attacker's forged cross-origin request (e.g., from an HTML form) cannot include this custom header, the server will reject it. This is often used in AJAX-heavy applications.

Prevention Best Practices

  • Prioritize CSRF tokens: Implement robust, cryptographically random, and session-bound CSRF tokens for all state-changing actions.

  • Use SameSite cookies: Configure SameSite=Lax or SameSite=Strict for sensitive cookies.

  • Validate Content-Type: For endpoints expecting JSON or XML, strictly validate the Content-Type header to prevent text/plain payloads from bypassing checks.

  • Educate developers: Ensure developers understand CSRF vulnerabilities and best practices for prevention.

Last updated