2
votes

Is it possible to protect stateless REST API from both XSS and CSRF attacks?

Currently, I'm using JWT token stored in secure/httpOnly cookie for stateless authentication. This should protect the API from most common XSS attack: stealing cookies with XSS-injected JavaScript and sending them to the attacker.

However, this doesn't protect the API from CSRF attack, where attacker would trick the authenticated user to follow a link to the particular web API call to actuate adverse transaction on behalf of the victim. How could I protect the API from this attack without introducing server side state?

Also, is it true XSS vulnerability would inheritedly allow CSRF type attack in the following scenario: Injected JavaScript would retrieve CSRF token from the client side state, DOM or the browser storage and prepare a malicious ajax call to the server. Browser would still automatically include the httpOnly cookie for the same origin request. Is there a way to get protected from this other than protecting from the XSS vulnerability in the first place?

1
CRSF Attacks mainly target cookies, as these could be sent to the server if carrying out a CSRF attack. So a relatively easy counter-measure is to use a special header with every API request. This header does not even need to carry a token, something like: "X-Requested-With": "XMLHttpRequest" actually should be enough.frontend_dev
In addition, cookies can be secured using the httpOnly Flag which prevents any attacker from reading such cookies. Hovever these must be set by the server, and while the combination of those two measures should be fairly secure (of course you still have to protect against various XSS attack vectors) it is not stateless, as then you need a classic session management on the server. I have exactly the same problem, and haven't found a good solution to make all of that really stateless, since we also need to secure static assets like html5 video as well. If you have found anything, let me know!frontend_dev

1 Answers

1
votes

You can generate a token (e.g. a UUID) and put it into the jwt token as well as send it back to the client. Then the client sends it during every each request in a header. Then the server can compare the token in the header and the token in the jwt token to make sure the request comes from the client who was aunthenticated.