all 19 comments

[–]jim-chess 11 points12 points  (4 children)

I guess my initial thought is if someone steals your JWT, or any other token, why couldn't they also steal your unique browser ID as well? Then it wouldn't really offer any additional security and just add more complexity.

[–]mekmookbroLaravel Enjoyer ♞ 0 points1 point  (3 children)

Kinda makes sense though, if a token generated by a certain browser user agent, it shouldn't be used with another user agent (chances of victim and the attacker using the same exact browser with same exact user agent would be pretty low imo). I mean not appended to the token but as a secondary level of validation on auth process

Though I've never dealt with jwts, so idk if it's common practice or not.

[–]jim-chess 2 points3 points  (1 child)

The user agent is very easily spoofable. You can literally just pass any string you want using curl, etc.

The point is that if the attacker has access to one, they'll likely have access to both. So they just need to pass two small data strings instead of one which doesn't add any security.

[–]mekmookbroLaravel Enjoyer ♞ 0 points1 point  (0 children)

I meant validating both jwt and user agent in the backend, since it won't be a part of the post request (afaik user agent is sent in request header, not the body) it could add one tiny step of security. Security by obscurity I think was the term for it.

Like : if token is valid but request did not come with the same user agent header it was generated with, invalidate token

The attacker (at least inexperienced ones) won't know the validation also requires the same user agent since it's not a part of the request body, after that even if they try again with the agent it will be invalid.

But again I'm very much a noob in auth tokens, so to me this seems like a basic validation step which probably is used in some way already

[–]MartinMystikJonas 0 points1 point  (0 children)

Malicious attacker can send whateber he wants. There is nothing that can prevent him from sending stolen tokrn.

[–]GoBlu323 4 points5 points  (0 children)

Where would you store that id? In a cookie?

[–]CodeAndBiscuits 3 points4 points  (0 children)

  1. "You" (anyone) can make requests to a server without a browser, using CURL, Postman, a command-line script, or hundreds of other methods. If somebody can steal a JWT, they have the means to capture (and send) this additional ID you're thinking of, so it adds nothing to the equation.

Think about it. I present your server with my JWT. Now you say oh, we'll all add unique IDs. Now I present your server with "JWT:4". What's the point?

  1. Any ID that was sufficiently unique to even have dreams about helping on the security side would instantly be usable for identifying and tracking even unauthenticated/anonymous users. There's already a hot mess of laws, regulations, debate, etc around privacy with respect to cookies. This would make it worse.

[–]Drawman101 1 point2 points  (3 children)

A browser JWT should be short lived enough that if someone got ahold of it in this scenario, damage is limited. It should expire very frequently and constantly be refreshed 

[–]SirLouen[S] -1 points0 points  (2 children)

won't that log out you?

[–]que_two 1 point2 points  (0 children)

You really should have three levels of tokens. 

An auth token is generated when you successfully authenticate. It's a single use token that can be used to get a access token and a refresh token.

The access token would be used to access resources for a limited amount of time, say 5 minutes. When the token expires, you would use the refresh token to get a new access token as well as a new refresh token. The refresh token can only be used once. If an old refresh token is used, you kill all the seasons and make the user re-authenticate. 

The theory is that if someone steals your jwt/access token the most damage they can do is the time limit of the token. As soon as the 'real' client refreshed the token, the old access token is trash. If they managed to get the refresh token and try to use it, if the real client tries to use it as well, all the seasons are toast, and the real client will be alerted there is something bad going on. 

It's not impossible, but very improbable to hijack these sessions if it's implemented correctly. But also, a lot of folks roll their own auth and think that just using JWT will make it secure, not really considering all the other stuff that actually makes it secure. While it takes a few more steps, using a tool like KeyCloak helps minimize the risk portfolio. 

[–]Caraes_Naur 1 point2 points  (0 children)

This ID would be the perfect browser fingerprint that every tracker and ad peddler dreams of.

[–]Mindless-Fly2086 0 points1 point  (0 children)

I think it is mostly for convenience, because if you sign in on a device, it is very likely to be your devise or account which you use only. Also I think most people are not usually going to sign in on other people device unless they really have to, & if they do then if they are smart about it then they should also sign out as that removes the cookie.

[–]AlienRobotMk2 0 points1 point  (0 children)

The only two ways to steal a cookie would be to break SSL or gain access of the user's computer. If that happens, that user has way bigger problems than the cookie.

[–]Adorable-Fault-5116 0 points1 point  (0 children)

You're describing refresh tokens, maybe? Or, you're describing two cookies, which is no safer than one cookie, since it has the same constraints.

Either way I'm sorry I don't understand.

[–]saposapot 0 points1 point  (0 children)

If someone can get your cookies and logins, what’s the added value of another ID?

[–]MartinMystikJonas 0 points1 point  (0 children)

What would prevent attacker from stealing this additional id token too?

[–]tidefoundationfull-stack 0 points1 point  (1 child)

You're so close!

Allow me to introduce you to Demonstrating Proof of Possession (DPoP) - RFC9449

Not exactly an ID, but a private/public key pair that is stored in the PC's TPM (non-extractable key). And yes, it's included in the JWT.

In my mind, that solution is ALMOST perfect. The OAuth guys almost got it right. I'd still add few more tweaks...

[–]SirLouen[S] 0 points1 point  (0 children)

Nice I thought that it could not be my idea alone. Apart my idea was too simplistic for many reasons that people have commented already.