cookiesoauth-2.0jwtmicrosoft-oauth

Handling Cookies with Size Over 4096 Bytes - Best Practices


I'm facing a challenge with handling cookies in a web application where I store both an access token and a refresh token issued by Microsoftonline. The combined size of these tokens can sometimes exceed the 4096-byte limit imposed by most browsers. I want to ensure that I follow best practices for managing this situation.

My question is: What is the recommended approach to handle cookies when their size exceeds 4096 bytes? Should I split the cookies into two separate ones, one for the access token and the other for the refresh token? Alternatively, is it better to store the access token on the server side and only include an identifier in the cookie?

I appreciate the convenience of having all necessary information stored in the cookie for stateless operation, but I'm concerned about exceeding the browser's cookie size limit. What are the pros and cons of these two approaches, and are there any other best practices for managing cookies in situations like this?


Solution

  • Here are some suggestions. Note that desktop and mobile browser limits for the cookie request header are 4KB. Some HTTP servers, such as NGINX, also have a 4KB default limit for header sizes. Each host can issue up to 20 cookies according to RFC 2109.

    COOKIE PATHS

    You will probably have 4 cookies in total. For any particular request, use of paths should then ensure that you stay under the 4KB limit. Here is an example:

    When cookies are stored in tokens, use a strong symmetric security algorithm to encrypt them. The key must be private to the backend, and rotated occasionally.

    EFFICIENT TOKENS

    Where supported, issue access and refresh tokens in an opaque format (similar to a UUID) for internet clients, so that token contents cannot be read. This is a privacy best practice and also results in smaller cookies, which should continue to be encrypted.

    If you can't use opaque tokens, an efficient token signing algorithm like ES256 can reduce the size of cookies considerably compared to RS256. You may see cookie sizes shrink by up to 50%. Eg here is a basic example ES256 JWT (about 440 bytes):

    eyJhbGciOiJFUzI1NiIsImtpZCI6IjE3OTg0MzM5LTY0NmItNDYzZS1hNzI1LTAxZTMzYTE1NTgwNyJ9.eyJpc3MiOiJodHRwczovL2xvZ2luLmF1dGhzYW1wbGVzLWRldi5jb20iLCJhdWQiOiJhcGkubXljb21wYW55LmNvbSIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgaW52ZXN0bWVudHMiLCJzdWIiOiJhNmI0MDRiMS05OGFmLTQxYTItOGU3Zi1lNDA2MWRjMGJmODYiLCJtYW5hZ2VyX2lkIjoiMTAzNDUiLCJyb2xlIjoidXNlciIsImV4cCI6MTcwOTE1MTUyOH0.RkUFMuTBktET8YeR4M65LES9PME13eRe56AzP8hMhCYEGFs1eyGki-pGzqx1Gc17EHVJ9VgiA5u4j2w28uUpDg
    

    BACKEND TOKEN STORES

    I prefer to avoid these if possible, since they add complexity and could become a vulnerability. In OAuth the authorization server should do the job of storing tokens for you, as is the case when opaque tokens are used. I therefore consider it a backup option, if cookie sizes get reduced further, rather than an option that should be used by default.

    JWT SOLUTION TO COMPARE AGAINST

    Out of interest I have used the cookies containing tokens pattern with both JWTs and opaque tokens. You can run my Online SPA which uses AWS Cognito JWTs to view requests. It works in all mobile and desktop browsers. When I have run this in an NGINX environment though, I had to increase the default max header size of the HTTP server. This is because Cognito issues large RS256 JWTs.