Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fetch, set-cookies and csrf

I m using Isomorphic fetch in my application and I m having some troubles dealing with CSRF.

Actually, I m having a backend that sends me a CSRF-TOKEN in set-cookies property :

enter image description here

I have read somewhere that it's not possible, or it's a bad practice to access this kind of cookies directly inside of my code.

This way, I tried to make something using the credentials property of fetch request :

const headers = new Headers({
            'Content-Type': 'x-www-form-urlencoded'
        });
        return this.fetcher(url, {
            method: 'POST',
            headers,
            credentials: 'include',
            body: JSON.stringify({
                email: '[email protected]',
                password: 'password'
            })
        });

This way, I m able to send my CSRF cookie back to my server to serve my need (it's a different one, because it s not the same request) :

enter image description here

My problem

My problem is that my backend needs to receive a x-csrf-token header and so I can't set it to my POST request.

What I need

How can I do to put the value of set-cookies: CSRF-TOKEN into the next request x-csrf-token header ?

like image 742
mfrachet Avatar asked Nov 30 '16 16:11

mfrachet


People also ask

How do I pass a CSRF token in Fetch?

To fetch a CRSF token, the app must send a request header called X-CSRF-Token with the value fetch in this call. The server generates a token, stores it in the user's session table, and sends the value in the X-CSRF-Token HTTP response header.

Can fetch set cookies?

If you set credentials to same-origin : Fetch will send 1st party cookies to its own server. It will not send cookies to other domains or subdomains. If you set credentials to include : Fetch will continue to send 1st party cookies to its own server.

How do you pass cookies in fetch request?

If you want to pass cookies with this request, you can do so by passing the credentials option to the fetch request. fetch("http://example.com/data.json", { credentials: "same-origin" }) . then(response => response. json()) .

Can CSRF steal cookie?

A session cookie can easily be hijacked from the browser of an authenticated user, after which the cookie-based session handling just ease the work of the attacker. However, by adding a CSRF token to the request Jack can prevent the CSRF attack.


1 Answers

It looks like in your scenario you are supposed to read from CSRF-TOKEN cookie. Otherwise it would be marked HttpOnly as JSESSIONID. The later means you cannot access it from the web page but merely send back to server automatically.

In general there is nothing wrong in reading CSRF token from cookies. Please check this good discussion: Why is it common to put CSRF prevention tokens in cookies?

You can read your cookie (not HttpOnly, of cause) using the following code

function getCookie(name) {
  if (!document.cookie) {
    return null;
  }

  const xsrfCookies = document.cookie.split(';')
    .map(c => c.trim())
    .filter(c => c.startsWith(name + '='));

  if (xsrfCookies.length === 0) {
    return null;
  }
  return decodeURIComponent(xsrfCookies[0].split('=')[1]);
}

So fetch call could look like

const csrfToken = getCookie('CSRF-TOKEN');

const headers = new Headers({
        'Content-Type': 'x-www-form-urlencoded',
        'X-CSRF-TOKEN': csrfToken
    });
    return this.fetcher(url, {
        method: 'POST',
        headers,
        credentials: 'include',
        body: JSON.stringify({
            email: '[email protected]',
            password: 'password'
        })
    });
like image 80
Igor Popov Avatar answered Nov 15 '22 17:11

Igor Popov