JSON Web Tokens (JWT) Security
SeidYassin.ApplicationSecurityConsultant.Dtssolution
• What is JSON Web Token?

• Why we use JSON Web Tokens?

• When should you use JSON Web Tokens?

• What is the JSON Web Token structure?

• How do JSON Web Tokens work?

• Security Concerns / Attack Types /
Agenda
What is JSON Web Token?
JSON Web Tokens are an open, compact and self-contained
industry standard RFC 7519 method for representing claims
securely between two parties.
RFC 7519
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwi
bmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2
QT4fwpMeJf36POk6yJV_adQssw5c
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwi
bmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2
QT4fwpMeJf36POk6yJV_adQssw5c
Compact: Because of its smaller size, JWTs can be sent
through an URL, POST parameter, or inside an HTTP header
Self-contained: The payload contains all the required
information about the user, avoiding the need to query the
database more than once.
JWT Security : The basics - Sessions
Browser Server Database
POST   /login
Username ….
Password ….
Select
Username …. AND Password ….
200 ok 
Set-Cookie : SESSIONID = A42
Found 
{…….}
Set-Cookie : SESSIONID = A42
Get /Homepage
200 ok
Hello  JOHN
Set
ID = A42
Get
ID = A42
Found 
{…….}
Memory
JWT Security : The basics
Browser Server
JWT Security : The basics
Browser
Server
Load Balancer
Server
JWT Security : The basics
Browser Load Balancer
Server
Server
Server
Server
JWT Security : The basics
Browser Load Balancer
Server
Server
Server
Server
ID=A41
ID=A41
JWT Security : The basics
Browser Load Balancer
Server
Server
Server
Server
ID=A41 ?
ID=A41
ID=A41 ??
JWT Security : The basics
Browser Load Balancer
Server
Server
Server
Server
Shared
Cache
ID=A41
ID=A42
ID=B41
ID=C40
ID=A41 ?
< Single Point
Of Failure >
JWT Security : The basics
Browser Load Balancer
Server
Server
Server
Server
Distributed
Cache
JWT Security : The basics
Browser Load Balancer
+ Sticky
Sessions
Server
Server
Server
Server
Distributed
Cache
How about …
Manage and Maintain the state at client side
JWT Security : The basics - JWT
Browser Server Database
POST   /login
Username ….
Password ….
Select
Username …. AND Password ….
200 ok 
Set-Cookie : JWT = H3.P4.S1
Found 
{…….}
Cookie: JWT = H3.P4.S1
Get /Homepage
200 ok
Hello  JOHN
Write + Sign
Verify + read
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwi
bmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2
QT4fwpMeJf36POk6yJV_adQssw5c
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwi
bmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2
QT4fwpMeJf36POk6yJV_adQssw5c
Three parts separated by dots (.), which are:
• Header
• Payload
• Signature
What is the JSON Web Token structure?
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwi
bmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2
QT4fwpMeJf36POk6yJV_adQssw5c
• Header: Token type and hashing algorithm

• Payload: User / verification content / Claims
• Signature: Header, payload, and secret
What a Signed Token will Look Like
xxxxxxx.yyyyyyy.zzzzzzz
JWT high-level representation
Header.Payload.Signature
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwi
bmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2
QT4fwpMeJf36POk6yJV_adQssw5c
JWT Structure : Header
xxxxxxx.yyyyyyy.zzzzzzz
Typically consists of two parts: 

• hashing algorithm being used, such as HMAC SHA256 or RSA. 

• type of the token, which is JWT, 

• This JSON is Base64Url encoded to form the first part of the JWT
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwi
bmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2
QT4fwpMeJf36POk6yJV_adQssw5c
JWT Structure : Payload
xxxxxxx.yyyyyyy.zzzzzzz
Payload contains the claims - statements about an entity (typically, the
user) and additional metadata. 

• Reserved claims: A set of predefined claims which are not mandatory but
recommended, to provide a set of useful, interoperable claims. Examples: iss
(issuer), exp (expiration time), sub (subject), aud (audience) 

• Public claims: These can be defined at will by those using JWTs. But to avoid
collisions they should be defined in the IANA JSON Web Token Registry or be
defined as a URI that contains a collision resistant namespace. 

• Private claims: These are the custom claims created to share information
between parties that agree on using them.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwi
bmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2
QT4fwpMeJf36POk6yJV_adQssw5c
JWT Structure : Signature
xxxxxxx.yyyyyyy.zzzzzzz
• Take the encoded header, the encoded payload, a secret, the algorithm
specified in the header, and sign it. 

• The signature is used to verify that the sender of the JWT is who it
says it is and to ensure that the message wasn't changed along the
way. 

• For example if you want to use the HMAC SHA256 algorithm, the
signature will be created in the following way:
What a Signed Token will Look Like
jwt.io
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwi
bmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2
QT4fwpMeJf36POk6yJV_adQssw5c
Authorization: Bearer <token>
Transmission of a JWT via HTTP Headers
Tokens
By Reference By Value
SESSIONID = 42 JWT= h432121.hso33jl.iwoe
Use case
JWT for API Authentication/Authorization
Security Concern
Security Concern
The leakage of sensitive information
• the payload is transmitted in plaintext, information leakage occurs if there is
sensitive information in the payload

• eg. 

• Credentials

• internal IP addresses through the tokens.
Security Concern
Weak algorithms for signature
JWT Signing Algorithms
The most common algorithms for signing JWTs are:
HMAC + SHA256 (HS256)
RSASSA-PKCS1-v1_5 + SHA256 (RS256)
ECDSA + P-256 + SHA256 ( ES256)
Security Concern
Weak Secret / Brute-Forcing HS256
• conduct offline brute-force attacks against the token by using wordlists of
possible secret-keys

• It is recommended to use sufficiently long (256 bit) keys to safeguard against
these attacks.
Please note the RFC7518 standard states that "A key of the same size as the hash output (for
instance, 256 bits for "HS256") or larger MUST be used with this algorithm." 
Tools :  jwt-cracker
Security Concern
Not Verifying the Algorithm - Signature Stripping attack
Modify the algorithm to none
• Some JWT libraries support the none algorithm, that is, no signature algorithm. 

• When the alg is none, the backend will not perform signature verification.

• After changing alg to none, remove the signature data from the JWT (only header + ‘.’ + payload + ‘.’) and
submit it to the server.
Security Concern
Not Verifying the Algorithm - Signature Stripping attack
Modify the algorithm to none
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0
NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2Mj
M5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQ
ssw5c
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0
NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2Mj
M5MDIjkl.
//header
{
alg: ‘HS256’
}
//payload
{
sub: '123',
name: ‘ahmed ali’,
admin: 'false'
}
//header
{
alg: 'none'
}
//payload
{
sub: '123',
name: ‘ahmed ali’,
admin: 'true'
}
Security Concern
Not Verifying the Algorithm - Signature Stripping attack
Modify the algorithm to none
CVE-2018–1000531 - INVERSOFT PRIME-JWT 

Most of the modern implementations now have an added security check that rejects tokens
set with ‘none’ algorithm when a secret-key was used to issue them.

If you receive a JWT with an unexpected algorithm, type header, etc, discard it, and stop
right there.
Security Concern
Changing the algorithm from RS256 to HS256
• The algorithm HS256 uses a secret key to sign and verify each message.
• The algorithm RS256 uses a private key to sign messages, and a public key to verify them.
• If you change the algorithm from RS256 to HS256, the backend code uses the public key as the
secret key and then uses the HS256 algorithm to verify the signature.
Consider the following example code, which could be present at the server:
jwt = JWT.decode(token, public_key)
signing our own token using HS256 with the public key of the RS256 algorithm
The backend code uses the RSA public key + HS256 algorithm for signature verification.
Security Concern
Changing the algorithm from RS256 to HS256
const decoded = jwt.verify(
token,
publickRSAKey,
{ algorithms: ['HS256' , 'RS256'] } //accepted both algorithms
)
//header
{
alg: 'RS256' => 'HS256'
}
//payload
{
sub: '123',
name: ‘ahmed ali’,
admin: 'false' => 'true'
}
 modification that attacker can make:
Security Concern
Changing the algorithm from RS256 to HS256
openssl s_client -connect <hostname>:443
openssl x509 -in cert.pem -pubkey –noout > key.pem
echo -n
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZW1vLnNqb2VyZGxhbmdrZW1wZXIubmxcLyIsImlhdCI6MTU0NzcyOTY2MiwiZXhwIjoxNTQ3Nzk5O
Tk5LCJkYXRhIjp7Ik5DQyI6InRlc3QifX0" | openssl dgst -sha256 -mac HMAC -macopt hexkey:
2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d494942496a414e42676b71686b6947397730424151454641414f43415138414d49494243674b
4341514541716938546e75514247584f47782f4c666e344a460a4e594f4832563171656d6673383373745763315a4251464351415a6d55722f736762507970597a7932
323970466c3662476571706952487253756648756737630a314c4379616c795545502b4f7a65716245685353755573732f5879667a79624975736271494445514a2b5
965783343646777432f68414633787074562f32742b0a48367930476468317765564b524d382b5161655755784d474f677a4a59416c55635241503564526b454f5574
534b4842464f466845774e425872664c643736660a5a58504e67794e30547a4e4c516a50514f792f744a2f5646713843514745342f4b35456c5253446c6a346b7377786
f6e575859415556786e71524e314c4748770a32473551524532443133734b484343385a725a584a7a6a36374872713568325341444b7a567a684138415733575a6c50
4c726c46543374312b695a366d2b61460a4b774944415141420a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a
2zobdg7sgeApcEaR9ngMTRZT1dkWiMJOWYkelzQu5Z8
Security Concern
Changing the algorithm from RS256 to HS256
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZW1vLnNqb2VyZGxhbmdr
ZW1wZXIubmxcLyIsImlhdCI6MTU0NzcyOTY2MiwiZXhwIjoxNTQ3Nzk5OTk5LCJkYXRhIjp7Ik5DQ
yI6InRlc3QifX0.2zobdg7sgeApcEaR9ngMTRZT1dkWiMJOWYkelzQu5Z8
Resolution
1. Use only one encryption algorithm (if possible) 2. Create different functions to check different algorithms
Security Concern
Reusing the same key across services
• Substitution attack
Service #1
Service #2
Jwt1
Jwt2
Security Concern
Reusing the same key across services
• Substitution attack
Service #1
Admin:true
Service #2
Admin: false
Jwt1
Jwt1
Security Concern
Reusing the same key across services
• Substitution attack

• Add Audience to payloads 

• Use different secret for each service
//header
{
alg: ‘HS256'
}
//payload
{
sub: '123',
name: ‘ahmed ali’,
admin: ‘false’,
aud: ‘service #1’
}
//header
{
alg: ‘HS256'
}
//payload
{
sub: '123',
name: ‘ahmed ali’,
admin: ‘True’,
aud: ‘service #2’
}
References
https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2019/
january/jwt-attack-walk-through/
https://habr.com/en/post/450054/
http://demo.sjoerdlangkemper.nl/jwtdemo/rs256.php
——————
https://www.youtube.com/watch?v=67mezK3NzpU
https://www.youtube.com/watch?v=rCkDE2me_qk
https://www.youtube.com/watch?v=DPrhem174Ws
Th.ank.You

Jwt Security