I'm currently learning JWT implementation with PHP and want to use JWT tokens instead of sessions for my RESTful application.
During signature creation, I'm doing something like this
token = base64Header + '.' + base64Payload + '.' + signature
Here we are just using base64 the Payload. If I paste in sites like https://jwt.io/#debugger, the Payload gets decrypted (even if the signature is wrong).
My questions,
Below is the sample code I wrote
<?php
$headers = base64_encode(json_encode([
"typ" => "JWT",
"alg" => "HS256"
]));
$claims = base64_encode(json_encode([
"sub" => "1234567890",
"name" => "John Doe",
"admin" => true,
"jti" => "870a3de5-ea7b-4062-abef-11180e530f5a",
"iat" => 1492603378,
"exp" => 1492606978
]));
$payload = $headers.".".$claims;
$signature = base64_encode(hash_hmac("sha256", $payload, 'secret', true));
$encodedJWT = $payload.".".$signature;
// eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImp0aSI6Ijg3MGEzZGU1LWVhN2ItNDA2Mi1hYmVmLTExMTgwZTUzMGY1YSIsImlhdCI6MTQ5MjYwMzM3OCwiZXhwIjoxNDkyNjA2OTc4fQ.nvw-bAUgr7H_xr3q8_Yz8rCNtMohtn2YlCmcLoLBWlc
To reiterate, whatever you do, don't store a JWT in local storage (or session storage). If any of the third-party scripts you include in your page is compromised, it can access all your users' tokens. To keep them secure, you should always store JWTs inside an httpOnly cookie.
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed.
JWT is a stateless session, so it does not need to be saved in a database in the server-side like cookies, it only exists in the client side. please notice that it is not encrypted it's just encoded which means you can use base64 decode and you will get the JSON object in clear.
JSON Web Tokens (JWT) can be signed then encrypted to provide confidentiality of the claims. While it's technically possible to perform the operations in any order to create a nested JWT, senders should first sign the JWT, then encrypt the resulting message.
If I paste in sites like https://jwt.io/#debugger, the Payload gets decrypted (even if the signature is wrong).
Third parties cannot verify the signature because they don't have the secret key. The payload doesn't get decrypted - it gets decoded.
Ideally you should not store sensitive data in the payload since the payload is only base64 encoded and not encrypted. This means anyone who gets a hold of the token can view the contents of the payload by simply base64 decoding it.
If you have a token in local storage of a web browser and your site has an XSS vulnerability it makes it trivial to steal the token. It's bad enough that the attacker has a valid JWT (which will hopefully expire soon anyway) but if it contains sensitive data then you're in real trouble. Imagine having to notify all users on your site that they must now change various bits of sensitive data about themselves because of a potential mass compromise.
Keep the JWT lightweight. Store the users ID, their roles/grants withing the system. If you feel like you have to add sensitive data to the payload try and rethink your solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With