Deserializing cookie with JWT token during authentication fails to deserialize properly

Viewed 186

I'm having problems deserializing cookies using Spring Security for my stateless application.

Calling https://localhost:8080/login and succesfully authenticating results in a cookie containing the JWT token and some other fields, notably Secure, HttpOnly, SameSite=None. So for instance, it looks like the following (token works only locally, is expired and doesn't contain useful information, feel free to steal):

token=eyJhbGciOiJIUzUxMiJ9.eyJ1c2VySWQiOiI2NzA1ZTk1YS1hOTgzLTRiMDItYmVjOC01ZGFkNDM0MzY0NzAiLCJleHAiOjE2MDkxNzA0Nzd9.9OF_iDuxlZ9Xk9v_YJJTDY0LCQ21mZENnKRafhYKv63KXZ3tkHzSZt0Ngskxp9-yaa10AEY5p1j44cGQ9KY-DQ; Max-Age=1800; Path=/; Secure; HttpOnly; SameSite=none; Domain=localhost

I've used a self-signed certificate and a .jks file to add https to my localhost calls to test the authentication flow. I've also tested that this cookie is actually correctly set in Insomnia/Postman.

My Spring Security config now requires a cookie with a valid token to be present for every request. This works fine. I ran into an issue however when I tried to require that the token has the same fields in the request, that it had when it was set:

require(cookieContainingToken.isHttpOnly
                && cookieContainingToken.secure
                && cookieContainingToken.name == "token")

Using the debugger, I can see that the cookie is present and contains the right token, but is no longer httpOnly and not secure. The path is null, the domain is null, and maxAge is -1. Furthermore, the javax.servlet.http.Cookie class used by Spring doesn't seem to have the sameSite attribute. Obviously, deserialization of the cookie didn't entirely work.

Is there a way to make deserialization of the cookie on incoming requests work properly? Or should I simply ignore these attributes for incoming requests and just validate the token?

1 Answers

As far as the relevance of HttpOnly, Max-Age and Secure si concerned , these were in place to helps mitigate the risks mainly originating from client side like client side script accessing the protected cookie (if the browser supports it), for transmission over secure communication and restricting the access through Javascript.

You definitely need to set these at the source of origin as in our case spring-boot app. I am unware of the reason behind the manipulation of cookie props but anyways yo are not going to validate those apart from jwt token claims with signature.

The beauty of signed jwt are that even if someone is able to steal it, it won't be usable unless he has the signing key. So your tokens are safe with you.

IMHO jwts are not made for client to read/decrypt or use it, it's just that you should receive it back thereby verifying the caller.

To add to your security, to can encrypt your signed jwt with org.jasypt.util.text.StrongTextEncryptor so that it's worthless for anyone except you.

Also you can keep different signing keys for both access and refresh tokens if you use.

Related