3 elements:

  1. A relevant action the attacker wants to trigger.
  2. Session handling is solely cookie-based
  3. Request parameters must be predictable

Trigger with a webpage that has a hidden form, etc. Deliver a link to the victim via e-mail, social media, comment on popular site, img src if it’s a GET,etc.

CSRF PoC generator is built-in to Burp

  1. Select a request and right click
  2. Engagement Tools→ Generate CSRF PoC
  3. Tweak the PoC to fine-tune
  4. Copy the generated HTML into a web page and view in a browser logged in to the vulnerable website

Common defenses:

  1. CSRF tokens
    1. Can be a hidden parameter generated per-user on a form
    2. Can be a header
    3. May be possible to bypass by switching HTTP methods
    4. May be possible to just omit the token and it won’t be validated
    5. Tokens may be assigned from a global pool. Log in as your user, get one, use it.
      1. Will need to intercept the original request since most CSRF tokens are one-use. Grab it and make it into a PoC
      2. CSRF token may be tied to a cookie, but not the session cookie. You can detect this if changing the session cookie logs you out but changing the CSRF cookie just results in an invalid CSRF token message.
        1. Use some feature of the website or subdomain to set a cookie you can control to set the CSRF token
        2. Same thing works if cookie is set to match a request parameter
  2. SameSite cookies
    1. Refers to same scheme (http(s)), same TLD and first-level domain. Not the same as origin which is the scheme, full domain, and port.
    2. Intended to prevent a third-party site from triggering a request to another site with the cookies included, which can help prevent CSRF, among other things.
    3. Possible settings are strict, lax, or none. Chrome now sets lax by default if none is specified.
    4. To set this just include a SameSite attribute in the cookie
    5. If a cookie is set with the SameSite=Strict attribute, browsers will not send it in any cross-site requests. This can have functionality impacts.
    6. Lax means that the cookie will be sent cross site if:
      1. The request uses the GET method.

        1. It may be possible to turn a POST into a GET and trigger it with a script, e.g.
        <script>
            document.location = '<https://vulnerable-website.com/account/transfer-payment?recipient=hacker&amount=1000000>';
        </script>
        
        1. This may also be possible through some frameworks providing overrides to the method, for example Symfony does this with form tags

          <form action="<https://vulnerable-website.com/account/transfer-payment>" method="POST">
          
          1. Additional example that uses a GET but sets the method to POST:

            GET /my-account/change-email?email=bob2%40dobbs.com&_method=POST HTTP/2
            
      2. The request resulted from a top-level navigation by the user, such as clicking on a link

      3. Not a background request, e.g. script/iframe/img and other resources. However script seems to work using the document.location method.

    7. None means that there is no cross-site protection. Used for tracking cookies, etc.
      1. Must include the Secure attribute to ensure it’s only sent over https or browser won’t set it.
    8. It may be possible to validate even strict SameSite protections using a client-side redirect that can be manipulated.
  3. Referrer validation