While writing the the second part of my Authentication and security for REST API in the context of Web Apps series of posts, I realized that discussing the different alternatives to store credentials token was more extensive than I previously thought.
This post focuses on storing and transmitting credentials out-of-band. This means the API is designed in such a way that the user-agent should not have access to the credential token directly (e.g., cookies). The other half of the discussion focuses on in band credential storage.
If you haven’t read Roy T. Fielding’s dissertation yet, you should at least go check his section on “Why are cookies not RESTful?”. It is a much better explanation than I could ever write up. His arguments basically applies to any automatically managed out-of-band storage.
Moreover, once the authentication token is completely out or reach of your app, you need an alternative API so your App still knows when to renew your token and have a way to access the additional data required to present a better UX (User roles and such).
Since out-of-band credential stores present challenges for Web App UX, their use cases are mostly limited to manage user credentials. Long term “Remember me” tokens can be construed as a form of user credentials. Any client with this token will be allowed to open a session under the identity of this specific user. Moreover, we already recommended to trade-in such long term tokens for a short term one as early as possible during a session. This is very similar to how user credentials are processed.
There are, currently, no manually managed out-of-band storage and transit solution. The Credentials Management API could fit this concept. However, the current specification draft requires the Web App to be able to access the private details of the stored credentials and manage how they are used to interact with the server. This makes it an in-band storage and is discussed in a different post.
Given that cookies have been the preferred way to store session IDs for decades now, many security features have been included to them. HttpOnly and Secure cookies are completely shielded from normal user code. This would prevent completely an XSS attack from stealing and storing the token for later use. However, there are still other attack vectors (known and unknown), such as XST, that could bypass these protections.
There is also the following point to consider: REST and HATEOAS’s goal is to make machine crawling of an API easy. They aim to be exploitable by software with no a priori knowledge of the API or the service behind it. Therefore, an attacker does not need to steal or copy any token. Simply by leveraging the API discoverability feature itself, they will be able to extract every single piece of information from the API, automatically.
Finally, having the browser automatically manage the tokens gives rise to the temptation to have the server seamlessly renew tokens automatically. This creates two additional issues:
First, since each request can carry two resources (a new token and whatever the result of the request is), it is not RESTful. Plus you cannot cache anything anymore. A, potentially expired, token might be served to the client, which is an issue even for local, private caches (such as a browser’s own cache).
The second issue has to do with the long-term/short-term tokens separation. In our initial suggestions for credentials container, we recommend long-term tokens should be, basically, treated as user credentials. Only ever to be used to generate a short-term token. The goal of this segregation is to prevent long-term tokens lingering exposed on the wire and manipulated continuously either by the app or the browser (thus increasing attack surface and theft possibility).
Since cookies cannot be stored off the wire by a browser, swapping a long term token for a short term one can only be done in one of three ways:
Any out-of-band data automatically managed by the browser is highly vulnerable to both types of CSRF attacks (impersonation and cookie injection), cookies included.
Non-browser agents can be classified in two categories when considering cookies:
For all these reasons, cookies SHOULD NOT be used to store REST authentication tokens.
However, there are case where the combination of software environment and UX requirements is such that cookies are the only option available… For this reason and this reason only, an integration of cookie-based tokens will be discussed in further parts of this series.
The other half of the discussion focuses on in band credential storage.