손상된 사용자 권한을 이용하는 JSON 웹 토큰에 대한 위협 분석
핵심 요약
Akamai 연구원들은 JSON 웹 토큰(JWT)을 손상된 사용자 권한을 이용한 공격 기법으로 분석했으며, 이는 OWASP(Open Web Application Security Project) API 보안 상위 10대리스크에 포함되어 있습니다. 또한 JWT 위협 및 트렌드와 관련된 다양한 시나리오를 파악했습니다.
JWT는 사용자를 안전하게 확인하기 위해 일반적으로 클라이언트와 서버 사이에서 토큰을 발행해 API를 보호합니다. 이러한 토큰은 가장 일반적으로 사용되는 확인 양식 중 하나로, JSON 오브젝트 형식으로 공유되는 정보를 포함합니다.
각 토큰은 암호화되지 않지만 인코딩되며, 확인 시그니처를 포함합니다. Akamai는 부적절한 구축 또는 낮은 엔트로피 및 짧은 암호 키로 인해 발생하는 JWT에 대한 여러 위협 중 일부를 조사했습니다.
JWT 사용자와 기업이 API에서 JWT를 토큰으로 선택할 경우 계정 탈취, 권한 확대, 데이터 유출과 같은 세 가지 잠재적 주요 리스크에 직면할 수 있습니다. 트래픽에서 관측한 바에 따르면, 대부분의 JWT는 이론적으로 보안 수준이 낮음에도 불구하고 대칭 알고리즘을 사용합니다.
이 게시물에서는 이러한 JWT 위협에 대처하는 방법에 대한 모범 사례를 제공합니다.
서론
JWT는 널리 사용되고 비교적 사용하기 쉽지만 많은 리스크가 숨겨져 있는 토큰 스키마입니다. 따라서 JWT의 구축 및 보안과 관련하여 이러한 리스크를 고려해야 합니다. JWT에 대한 주요 리스크 중 하나는 OWASP API 보안 상위 10대리스크에 나타난 손상된 사용자 권한입니다.
손상된 사용자 권한은 API가 요청을 제출한 사용자의 ID와 인증정보를 제대로 확인하지 못할 때 발생합니다. 안타깝게도 이 리스크는 JWT와 관련하여 관찰되는 일반적인 취약점으로, 공격자가 다른 사용자의 계정으로 가장하거나 해당 계정으로 접속해 권한 상승 및 데이터 유출을 유발할 수 있습니다.
파이프라인 보호
JWT는 API 및 웹 애플리케이션에 일반적으로 사용되는 인증 토큰입니다. 트래픽에서 관측한 바에 따르면 웹 애플리케이션이 더 많은 API를 도입해 고객에게 제공함에 따라, 서로 다른 API 엔드포인트에서 원활한 인증의 필요성이 증가하고 있습니다.
API는 기업의 인증 및 권한 부여 메커니즘을 보관하며 데이터베이스를 쿼리하여 기업의 기능이 대부분 노출되는 주요 파이프라인입니다. 이러한 이유로 JWT의 위협은 API 영역에서 더욱 심각해지고 있습니다. 이 블로그 게시물에서는 JWT의 기본 사항, JWT에 대한 6가지 위협, 그리고 이러한 위협을 해결하는 방법에 대해 알아봅니다.
JWT의 기본 사항
JWT 는 웹 애플리케이션, 모바일 애플리케이션, API에서 데이터를 전송하기 위해 시그니처가 포함된 JSON 데이터를 전송하는 형식으로, 주로 인증 목적으로만 사용됩니다. JWT의 구조는 점으로 구분된 헤더(JOSE 헤더라고도 함), 페이로드, 시그니처의 세 가지 요소로 구성됩니다(그림 1).
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIiLCJpYXQiOjE2NzYyMTc5NTAsImV4cCI6MTcwNzc1Mzk1MCwiYXVkIjoiYWthbWFpLWJsb2ciLCJzdWIiOiIiLCJjb21wYW55IjoiQWthbWFpIiwidXNlciI6IkFrYW1haS1yZWFkZXIiLCJhZG1pbiI6Im5vIn0.kMPz3Z7BSlBTJKijD8bcrpzTZejX7VCZ77w5oQwJO6I
그림 1: JWT 구조의 세 가지 구성 요소에 대한 예시
헤더와 페이로드
헤더와 페이로드는 모두 URL 보안을 위해 Base64로 인코딩되며, IETF에서 지정한 필드 권장 사항을 충족합니다(그림 2). '인코딩'은 사람이 직접 읽을 수는 없지만 서버에서 쉽게 디코딩할 수 있음을 의미합니다. 인코딩의 목적은 데이터의 무결성과 유용성을 보장하고 'URL 보안'을 유지하기 위해서입니다. 이는 웹 브라우저에서 사용하는 문자가 중첩되지 않게 해줍니다.
JOSE 헤더는 JWT 및 JSON 웹 암호화(JWE) 모두에 사용됩니다. 이때 JWE는 기본적으로 암호화된 JWT이므로 대부분의 일반적인 JWT 공격을 방지하는 데 도움이 됩니다. 선택한 토큰 방법을 지정하는 필드는 'typ'(typ:JWT/JWE)입니다. 페이로드는 구축 방식에 따라 등록된 필드(IANA(Internet Assigned Numbers Authority)에서 요구함) 또는 사용자 정의 필드를 포함할 수 있습니다.
그림 2: 인코딩된 JWT
시그니처
시그니처의 목적은 토큰을 확인하는 것입니다. 즉, 서버에서 토큰을 생성한 후 데이터가 변경되지 않았는지 확인하는 것입니다.
시그니처는 다음과 같은 두 가지 기본 단계로 생성됩니다.
헤더와 페이로드에서 점으로 구분된 암호화 알고리즘(예: MAC) 적용(알고리즘은 암호 키 사용)
암호화된 헤더 및 페이로드에 해싱 알고리즘(예: SHA256) 적용
JWT를 사용할 때 서버는 시그니처를 확인해 직접 토큰을 검증합니다. (검증에 사용되는 다양한 알고리즘은 본 게시물 뒷부분에서 설명합니다.)
JWT는 규모에 상관없이 사용이 간편하고 구축이 쉬우며, 서버의 필수 데이터를 클라이언트 측에 저장하기 때문에 웹 애플리케이션의 인증에 널리 사용되고 있습니다. 그러나 시그니처가 포함되어 있어도 JWT와 관련된 리스크는 여전히 존재합니다. JWT는 일반 텍스트를 사용하며 매번 여러 개의 페이로드 필드로 구축됩니다. 따라서 공격표면이 넓고 오류의 여지가 많습니다.
Akamai는 JWT가 직면한 보다 일반적이고 흥미로운 위협 중 일부를 조사함으로써 취약점을 더욱 효과적으로 파악하고 악성 행동을 쉽게 탐지하며, 리스크를 효율적으로 방어하고 잠재적인 악용으로부터 보호하는 데 필요한 보안 조치를 마련할 수 있습니다.
JWT 이용 시 사용자에게 더 안전한 접근 방식을 제공하고 보안 전문가와 관리자가 실사를 수행하는 데 필요한 툴과 권장 사항을 제공하는 것이 Akamai의 목표입니다.
JWT에 대한 6가지 위협
1. 서버에서 검증 없이 토큰을 사용하도록 허용
JWT는 암호화 대신 시그니처를 사용하기 때문에 사용 전에 검증을 거쳐야 합니다. 애플리케이션에서 검증을 전혀 수행하지 않는 가장 기본적인 위협 시나리오에서 공격자는 페이로드(예: 권한 확대)를 편집하고 시그니처를 그대로 두거나, 시그니처를 삭제하고 더 높은 권한을 얻을 수 있습니다.
또 다른 방법은 헤더에서 'alg' 매개변수를 사용하는 것입니다. 이 매개변수는 토큰 시그니처에 사용된 알고리즘을 나타냅니다. 'none'은 정상적인 값이며 이러한 JWT를 비보안 JWT라고 합니다. 이 경우 누구나 쉽게 토큰에 시그니처를 포함할 수 있습니다. 백엔드에서 JWT를 확인하도록 구축할 수도 있습니다.
먼저 헤더에서 'alg' 필드를 찾습니다. 그런 다음, 지정된 알고리즘을 사용해 토큰을 확인합니다. 'none' 알고리즘은 해당 토큰에 대한 시그니처 및 확인이 필요하지 않음을 나타냅니다. 토큰의 페이로드, 헤더(alg:none 설정), '자체 시그니처'(시그니처 삭제)로 편집되면 공격이 성공하게 됩니다.
예
그림 3은 디코딩된 JWT의 예를 보여줍니다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiZXhhbXBsZSBuYW1lIiwiaWF0Ij
oxNjU5MjM5MDIyfQ.PrhAp2DUWXoL01_odyLATuzrwn5rMtY1IVsP8y4LH5E
decoded:
{
"alg": "HS256",
"typ": "JWT"
}
.{
"name": "example name",
"iat": 1659239022
}
그림 3: 디코딩된 JWT의 예
여기서 API 엔드포인트는 확인을 위해 선택한 알고리즘으로 페이로드의 'alg' 필드를 사용한다고 가정합니다.
하지만 JWT를 편집하려 합니다(그림 4). 이러한 방식으로 다른 사용자의 유효한 JWT를 변조할 수 있습니다.
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJuYW1lIjoiZXhhbXBsZSBuYW1lIiwiaWF0Ijo
xNjU5MjM5MDIyfQ.
decoded:
{
"alg": "none",
"typ": "JWT"
}
.{
"name": "other person's name",
"iat": 1659239022
}
그림 4: alg:none을 악용하기 위해 JWT를 편집했습니다.
모범 사례: 이 경우는 간단합니다. 항상 토큰을 사용하기 전에 미리 정의된 하드 코딩 알고리즘을 사용해 검증합니다. alg 매개변수를 검증 알고리즘의 포인터로 사용하지 않습니다.
2. 서로 다른 애플리케이션에 동일한 비공개 키 사용
서로 다른 애플리케이션에 대해 별도의 등록 정보를 가지고 있는 회사들이 많습니다. 동일한 비공개 키를 사용하면 두 애플리케이션에서 모두 유효한 토큰이 생성되지만 사용자 ID는 다릅니다. 이 경우 첫 번째 애플리케이션 토큰을 사용해 두 번째 애플리케이션에 요청을 제출하기만 하면 사용자의 의도와 상관 없이 계정을 탈취할 수 있습니다(그림 5).
모범 사례: 또 하나의 간단한 기본 룰입니다. 사용자 ID를 구분하는 경우 서로 다른 비공개 키를 사용해야 합니다.
3. 약한 시그니처 알고리즘 사용
알고리즘에는 대칭형(HSXXX) 및 비대칭형(RSXXX,ESXXX,PSXXX)의 두 가지 주요 계통이 있습니다. 대칭 알고리즘에는 하나의 공유 암호가 필요합니다. 비대칭 알고리즘에는 비공개 키와 공개 키가 필요합니다(표 1).
대칭 |
|||
---|---|---|---|
HSXXX |
HMAC + SHA |
비교적 약한 알고리즘 |
공유 암호 사용 |
비대칭 |
|||
RSXXX |
RSA + SHA |
보다 안전한 알고리즘 |
비공개 키와 공개 키 사용 |
ESXXX |
ECDSA + SHA |
세 가지 중 가장 안전한 알고리즘 |
비공개 키와 공개 키 사용 |
표 1: 알고리즘의 두 가지 주요 계통
공격자의 관점에서 대칭 알고리즘은 무차별 대입이 용이하고 공개 키를 수집할 필요가 없으며, 컴퓨팅 시간의 효율을 최대한 높일 수 있습니다. 트래픽에서 관측된 바에 따르면, 대칭 알고리즘이 비대칭 알고리즘보다 더 널리 사용되고 있습니다(그림 6).
이론적으로 대칭 알고리즘은 필요한 컴퓨팅 시간이 더 짧기 때문에 대규모 환경에서 비대칭 알고리즘보다 성능이 더 우수할 수 있습니다.
모범 사례: 비대칭 알고리즘을 사용합니다. 현재 가장 안전한 암호화 방식인 ECDSA 알고리즘을 사용할 것을 추천합니다. 암호의 엔트로피가 매우 높고 길이가 충분히 길면 적절하게 보안된 대칭 키도 괜찮습니다.
4. 짧거나 엔트로피가 낮은 비공개 키 선택
짧거나 엔트로피가 낮은 비공개 키는 낮은 비용의 빠른 무차별 대입 공격에 노출될 수 있습니다. 그래픽 처리 장치(GPU)와 함께 고성능 클라우드 환경에 설치해 쉽게 사용할 수 있는 크래킹 소프트웨어도 존재합니다. GPU 성능이 빠르게 발전하면서 크래킹 성능에 영향을 주고 있습니다. 오늘날의 고급 그래픽 카드는 3년 전보다 거의 2.5배 빠른 크래킹이 가능합니다.
3년 전 엔트로피에 상관없이 8자리 비공개 키를 크래킹하는 데 걸리는 시간과 현재 시간을 비교한 수치가 표 2에 나와 있습니다.
고급 그래픽 카드 |
크래킹에 걸리는 시간 |
---|---|
3년 전 |
10.5일 |
현재 |
4.5일 |
표 2: 8자리 비공개 키를 크래킹하는 데 걸리는 기간
몇 년 전에는 크래킹하는 데 24시간이 걸리던 7자리 비공개 키를 지금은 90분 이내에 크래킹할 수 있습니다. 이 공격의 독특한 특징은 기업 측에서 방어할 기회도 없이 또는 사용자가 이러한 종류의 공격을 받고 있음을 알 수 없도록 오프라인으로 실행된다는 점입니다.
국가가 후원하는 공격자가 이 공격을 위해 오케스트레이션된 시스템을 생성하기도 합니다. JWT의 비공개 키를 보유한 공격자는 사용자의 ID만 알고 있어도 다른 사용자로 가장해 시그니처가 포함된 토큰을 변조할 수 있습니다.
모범 사례: 10자 이상의 길고 엔트로피가 높은 비공개 키를 선택합니다. RSA 암호 생성기를 사용하는 것이 좋습니다.
5. JWT의 페이로드에 민감한 데이터 보관
JWT는 Base64 URL로 인코딩되므로 페이로드가 암호화되지 않습니다. DB 이름, 모든 종류의 증분 ID 또는 서버 내부 필드 및 데이터를 저장하면 데이터가 과도하게 노출되어 공격자가 다른 공격 기법(예: 손상된 오브젝트 수준 권한)을 사용할 수도 있습니다.
모범 사례: JWT에 민감한 데이터를 저장하지 않습니다. 민감한 데이터를 저장해야 하는 경우 JWE를 사용합니다.
6. 키 혼동
비대칭 알고리즘에서는 비공개 키를 사용해 JWT(시그니처 부분)를 변조하고 공개 키를 사용해 JWT를 검증합니다. 공격자는 헤더에 지정된 알고리즘을 대칭 알고리즘(예: HS256)으로 변경하고 서버에서 정상적으로 확인에 사용하는 공개 키로 시그니처를 생성할 수 있습니다.
이러한 경우, 제대로 구축되지 않은 백엔드에서 공개 키를 사용하고 헤더에 지정된 공격자로 대칭 알고리즘을 실행해 공격자가 변조한 JWT를 성공적으로 확인합니다.
예
그림 7은 새 JWT를 변조하는 서버 프로세스를 보여주고, 그림 8은 서버의 JWT 확인 프로세스를 보여줍니다.
마지막 확인 절차에서 다음 두 가지 이유 중 하나 또는 두 가지 모두로 인해 오류가 발생할 수 있습니다.
헤더와 페이로드는 편집되었지만 시그니처는 편집되지 않음
올바른 알고리즘 또는 올바른 키의 구성이 잘못됨
그림 9는 키 혼동 공격을 보여줍니다.
마지막 단계: 서버는 그림 8과 같은 프로세스를 통해 토큰을 확인하며, alg 필드를 신뢰합니다. 그리고 공개 키를 암호로 사용해 HS256 알고리즘을 실행하여 토큰을 확인하며, 이는 공격자가 계획한 것과 정확히 일치합니다.
모범 사례: 확인 프로세스에서 미리 정의된 알고리즘을 사용하고 사용자 입력을 신뢰하지 않습니다.
결론
JWT는 가장 일반적인 인증 토큰입니다. 인증된 상태에서는 자주 로그인할 필요 없이 여러 웹 애플리케이션과 API를 사용할 수 있습니다. 그러나 JWT는 암호화되지 않으며, 보안을 염두에 두고 구축되지 않기 때문에 많은 위협에 노출되어 있습니다.
컴퓨터 성능이 빠르게 진화하면서 취약한 암호 키는 리스크에 노출되고, 단 며칠 만에 이러한 키의 보안이 깨질 수 있습니다. JWT의 경우 이러한 종류의 공격은 기업에서 알지 못하는 새에 오프라인으로 실행될 수 있습니다.
대칭 알고리즘은 공격자가 쉽게 이용할 수 있는 가장 일반적인 종류의 알고리즘입니다.
인증 공격과 같은 보다 복잡한 위협도 존재하지만, 공격자가 인증 공격을 자동화하기는 어렵습니다. 그러나 간단한 JWT 공격 기법은 자동화가 가능해 대규모로 악용될 수 있습니다.
이를 포함한 여러 가지 이유로 인해 사용자는 JWT의 취약점 그리고 잠재적인 악용을 방어하기 위해 구축할 수 있는 최고의 보안 체계를 인식해야 합니다. 이 분석이 OWASP API 보안 10대 주요 위협 중 하나인 손상된 사용자 권한으로부터 JWT를 보호하는 데 유용한 가이드가 되기를 바랍니다.