Why CSRF token should be in meta tag and in cookie

2020-05-14 18:42发布

问题:

What's the need of to put CSRF token name and value inside <head> tag using <meta> like:

e.g:

<meta content="authenticity_token" name="csrf-param" />
<meta content="4sWPhTlJAmt1IcyNq1FCyivsAVhHqjiDCKRXOgOQock=" name="csrf-token" />

I've read about concept to keep CSRF value in cookie but does not find about why to keep inside <head> tag.

回答1:

To prevent CSRF you need a value that is submitted with the request that cannot be sent by a malicious site. Authentication cookies are not suitable because if an attacker can make the browser send a request to the victim site, the cookies will automatically be submitted.

For example, by submitting a form via JavaScript contained on www.evil.com to attack the user's session on www.example.com:

<form method="post" action="https://www.example.com/executeAction">
    <input type="hidden" name="action" value="deleteAllUsers">
</form>

<script>document.forms[0].submit()</script>

Storing an anti CRSF token within the page is the OWASP recommended solution for preventing another website from submitting the form, as the random token in the user's session cannot be read by www.evil.com due to the Same Origin Policy preventing JavaScript on www.evil.com reading the page content of www.example.com.

These tokens can be stored anywhere within the page. Most commonly it will be within hidden form fields, but they could also be stored within HTML 5 data- attributes. It seems like using meta tags is simply another way it can be stored where the JavaScript can include it in any form submissions the page makes.



回答2:

CSRF tokens normally go in a form as hidden form fields. Putting them in a meta tag only makes sense if you are using JavaScript. JavaScript could read the tokens from the meta tag and post them to an action.

You wouldn't want to put a CSRF token in a cookie because the cookie will be sent for every request to the specific website from the web browser regardless of its origin. The only exception would be secure cookies, which are supposed to follow the same-origin policy.



回答3:

That's because there's nothing stopping an offending website from POSTing data to a legitimate website which could include your authentication ticket and your CSRF token. Imagine this scenario...taken from ASP.NET

  1. A user logs into www.siteA.com, using forms authentication.
  2. The server authenticates the user. The response from the server includes an authentication cookie.
  3. Without logging out, the user visits a malicious web site. This malicious site contains the following HTML form:

    <h1>You Are a Winner!</h1>
        <form action="http://siteA.com/api/account" method="post">
            <input type="hidden" name="Transaction" value="withdraw" />
            <input type="hidden" name="Amount" value="1000000" />
     <input type="submit" value="Click Me"/>
        </form>
    

Notice that the form action posts to the vulnerable site, not to the malicious site. This is the “cross-site” part of CSRF.

The user clicks the submit button. The browser includes the authentication cookie with the request. The request runs on the server with the user’s authentication context, and can do anything that an authenticated user is allowed to do.

So basically, when siteA.com receives the CSRF attack it should match the CSRF token in the cookie against the one in the meta tag. A legit request will include both, however, a forgery attack will only include the CSRF token specified in the cookie.



回答4:

The only option I could imagine is to make that data accessable from JavaScript. Of cause just in case that the cookies are http only.