4

I have a custom authentication and authorization scheme based on three JWT tokens - reference (opaque) token, access token and refresh token. Backend sets reference token in a cookie and submits it with every request to the server.

Since, I'm using cookies, I need to prevent CSRF attack. I have written this SO thread and this stormpath article, but I still do not get the workflow, that I should follow to prevent CSRF attack.

My reference token payload looks similar to

{
    "iss": "http://galaxies.com",
    "exp": 1300819380,
    "scopes": ["explorer", "solar-harvester", "seller"],
    "sub": "tom@andromeda.com",
    "jti": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e"
}

just instead of xsrfToken property, I'm using a standard jti field. So, my client has this reference token with this jti field, this reference token is submitted to the server with every request, the server can decode this reference token and find by jti value corresponding access token in its cache. Now I wonder if this scheme prevents me from CSRF attacks or should I do some extra steps on the server side and client side to do this?

What I do not really get is why I should set some new X-XSRF-TOKEN header on the server side and what should I do with this header later.

Jacobian
  • 207
  • 1
  • 3
  • 13

2 Answers2

3

I am in the same situation as you, and here is how I understand the process:

  • The server sends the JWT token via Set-Cookie ... ; Secure ; HttpOnly. This will prevent Javascript on the client to read the JWT token, and hence it will prevent XSS attacks to steal the JWT token.

  • The server also sends a XSRF token that the Javascript on the client side can access, either in an additional header, in a client-side readable cookie, or as answer to the JWT token request. The client must then actively add this XSRF token to every request, for example as an additional header. The XSRF token is also part of the JWT token, so the server can verify that both match.

    This prevents CSRF attacks, because while the CSRF attacker can cause the cookie with the JWT token to be sent along with a request, he cannot read the XSRF token, and therefore cannot add this to the request.

  • The refresh token works in the same way.

This does not prevent the scenario where a XSS attack executes requests by including the XSRF token himself. It only prevents an XSS attack from stealing the complete token, and using it somewhere else. However, given that XSS attacks can pretty much do anything client-side Javascript can, this is probably as far as one can go.

Protecting the access JWT token against theft via XSS isn't that important, however protecting the refresh JWT token against theft is extremely important. The access JWT token hopefully has a short expiration time, but a stolen refresh JWT token cannot be revoked, as the token is stateless, so it will grant the attacker unlimited access. One can still change the keys used to sign the JWT token, maken all JWT tokens invalid.

The hwole process also does not protect against any kind of MITM attack, so using https is important.

As the XSRF really can be anything, I don't see why one couldn't use the jti field that is already present. However, the extra effort on the client side to add this information to every request is crucial.

dirkt
  • 131
  • 4
0

In short XSRF attack could be exploited when you visit an attacker website and click on some form which triggers for example money transaction on some online banking system that doesn't have XSRF protection, of course you must also have an active session on that system.

To be the attack successful, all of yours session cookies should be transferred to the banking system and since all of that cookies are transferred by default by the browser, the attack would be successful.

So to prevent the attack something in addition should be requested by the server, in the case with XSRF that thing is a token, so called XSRF token.

In your case you'd used the reference cookie as XSRF cookie and as session cookie, so the attack would be exploitable. Which means that you must separate the XSRF token from the reference cookie

RaISug
  • 9
  • 1
  • I don't understand what you mean by "reference cookie", or why you say it's a problem that the XSRF and session cookies are the same cookie. Splitting them into two separate cookies wouldn't change anything usefully. – Macil Nov 09 '18 at 22:16
  • 1
    I didn’t meant that there should be two cookies. There should be only one, the session cookie. But in order the request to succeed, also an additional token should be send (the XSRF token). But not as a cookie, instead it could be send as a header or form param. – RaISug Nov 09 '18 at 22:24