API가 클라이언트와 서버 간 데이터를 효율적으로 교환하기 위한 현대 애플리케이션의 핵심 구성 요소로 자리 잡으며 API 보안 또한 필수 요소로 떠올랐습니다. 이번 글에서는 OWASP API2:2023 – Broken Authentication을 중심으로, 해당 취약점이 발생하는 원인부터 실제 공격 시나리오, 실무적 대응 방안을 정리했습니다.
🧩API 인증(Authentication)이란?
API 인증(Authentication)은 애플리케이션이 요청을 보낸 클라이언트가 누구인지 식별하고, 해당 사용자가 시스템에 접근할 수 있는지를 확인하는 과정입니다. 현대의 웹 애플리케이션에서는 인증을 위해 세션 기반 인증, 토큰 기반 인증, OAuth 등 다양한 방식이 사용됩니다. OWASP API2:2023 Broken Authentication 항목에서 지적하는 주요 문제들은 JWT를 잘못 검증하거나 처리하는 과정에서 발생하기 때문에 토큰 기반 인증의 핵심 요소인 JWT(JSON Web Token)을 중점적으로 살펴보겠습니다.
🤔JWT란 무엇인가?
JWT는 헤더(Header), 페이로드(Payload), 서명(Signature) 세 부분으로 구성되어 있으며 각 구성 요소는 . (마침표)로 구분됩니다. 이들은 모두 Base64 URL-Safe 방식으로 인코딩되기 때문에, 토큰 자체는 누구나 쉽게 디코딩 해 내용을 확인할 수 있습니다.
💡Base64 URL-Safe Encode란?
일반적인 Base64 인코딩 결과를 URL이나 파일 경로에 안전하게 사용하기 위해 일부 문자를 변형한 방식입니다. URL-safe 방식에서는 + → – , / → _ 로 치환되며, 이는 JWT의 헤더/페이로드/서명 구조에 그대로 사용됩니다.
– 헤더에는 토큰 타입과 사용할 알고리즘 정보가 담기고,
– 페이로드에는 사용자 정보, 만료 시간( exp ), 발급 시점( iat ), 활성화 시점( nbf ) 등 다양한 클레임(Claim)이 포함됩니다.
– 서명은 헤더와 페이로드를 결합한 뒤 서버가 보유한 비밀키로 생성되는 값으로, 토큰이 위조되지 않았음을 보장하는 핵심 요소입니다.
🔍 JWT의 토큰 무결성 검증 절차는?
헤더와 페이로드는 단순히 Base64 URL-Safe 방식으로 인코딩된 값이기 때문에 누구나 쉽게 내용을 디코딩하고 수정할 수 있습니다. 그러나 서명은 서버가 가진 비밀키 없이는 생성할 수 없으므로, 이 서명을 통해 토큰의 무결성을 검증하게 됩니다. 클라이언트는 API 요청 시 Authorization 헤더에 Bearer <token> 형태로 JWT를 전송하며, 서버는 다음과 같은 절차를 통해 토큰을 검증합니다.
1️⃣서명이 유효한지 검증해 토큰이 변조되지 않았음을 확인합니다.
2️⃣만료 시간( exp ), 발급 시점( iat ), 활성화 시점( nbf ) 등 클레임(Claim) 값이 정상인지 검증해 토큰의 사용 가능 여부를 판단합니다.
3️⃣검증에 통과한 토큰이라면, 요청한 자원에 접근할 권한을 부여하고 API 처리를 진행합니다.
이처럼 JWT는 서명을 통해 토큰의 위변조 여부를 검증할 수 있으며, exp 등의 클레임을 통해 토큰의 만료 여부를 판단할 수 있도록 설계된 인증 토큰입니다.
그러나 서버가 서명 검증을 생략하거나, 만료 시간을 제대로 확인하지 않거나, 비밀키를 안전하게 관리하지 못한 경우 인증 절차는 쉽게 무너질 수 있습니다. 검증이 부실한 환경에서는 만료된 토큰이 재사용되거나 변조된 토큰이 정상적으로 승인되어, 공격자가 정상 사용자처럼 인증을 통과할 수 있습니다.
이처럼 인증 체계가 제 역할을 하지 못하는 상태를 OWASP에서는 API2:2023 – Broken Authentication으로 분류합니다.
🚨JWT 검증 실패로 발생 가능한 공격 시나리오
JWT(Json Web Token)는 전송되는 데이터의 위변조를 방지하기 위해 서명을 포함합니다. 그러나 서버가 JWT 헤더에 포함된 알고리즘 값을 그대로 신뢰하거나, 허용 가능한 알고리즘을 강제로 제한하지 않은 경우 알고리즘을 none 으로 변경해 서명 검증을 우회할 수 있습니다.
일부 구 버전의 JWT 라이브러리에서는 “alg”: “none” 을 허용해, 서명 검증 절차가 생략되는 문제가 존재합니다. 이 경우 공격자가 임의로 만든 토큰도 정상 토큰으로 처리되어 인증이 사실상 무력화됩니다.
아래는 이러한 환경에서 공격자가 실제로 수행할 수 있는 단계별 시나리오입니다. (JSON에는 주석이 없지만 이해를 돕기 위해 //을 사용했습니다.
1️⃣ 정상 JWT 확보
브라우저 개발자 도구, 프록시 캡처, 탈취 등을 통해 정상 토큰을 하나 확보합니다.
|
// 클라이언트 요청에서 캡처한 JWT 예시 |
2️⃣ JWT를 디코딩 한 뒤, 헤더의 알고리즘을 “none”으로 변경합니다.
|
// 원본 { // 변경 |
3️⃣ 또한, 페이로드를 원하는 내용으로 변경합니다.
관리자 계정(추측 필요) 혹은 특정 사용자로 변조합니다.
|
// 원본 // 변경(관리자 계정 정보 추측) |
4️⃣ 서명 부분을 제거한 뒤, 헤더와 페이로드를 Base64로 재인코딩해 서버로 전송합니다.
토큰에 서명이 없더라도 페이로드 뒤에는 마지막 . (마침표)를 포함해야 합니다. 이는 JWT의 3-파트 구조(Header.Payload.Signature)를 유지해 서버가 파싱 에러 없이 정상적으로 토큰을 처리하도록 하기 위함입니다.
|
// 클라이언트 요청에서 캡처한 JWT 예시 // 알고리즘을 none으로 변경하고 서명 부분을 제거한 JWT 예시 |
5️⃣ 서버가 “alg”: “none”을 허용하는 경우, 해당 토큰은 서명 검증 없이 그대로 인증 절차를 통과합니다.
none 알고리즘이 허용된 환경에서는 공격자가 로그인 과정을 거치지 않고도 관리자 계정으로 위장한 토큰을 직접 생성할 수 있습니다. 이렇게 만들어진 토큰은 서버에서 정상 토큰으로 처리되기 때문에, 공격자는 관리자 전용 API를 호출해 사용자 목록 조회, 시스템 설정 변경, 계정 정보 열람, 수정, 삭제 등 다양한 민감한 작업을 수행할 수 있습니다.
또한, JWT에 만료 시간( exp )이 없거나 지나치게 길게 설정된 경우에도 유사한 위험이 발생합니다. 토큰이 XSS나 네트워크 스니핑 등을 통해 유출되면 회수할 수 있는 방법이 없기 때문에, 공격자가 장기간 정상 사용자로 위장해 시스템에 접근할 수 있습니다.
이와 같이 서명 검증 우회( alg: none )와 만료 시간( exp ) 검증 누락은 API 인증을 무력화하는 주요 원인입니다.
🔐JWT 기반 인증 과정에서 발생가능한 취약점을 방지하기 위한 보안 조치
☑️ 알고리즘 및 서명 검증
서버는 none 알고리즘을 허용해서는 안 됩니다. 또한 JWT의 서명이 누락되었거나 검증 과정에서 유효하지 않은 것으로 판단될 경우, 해당 요청은 즉시 거부해야 합니다.
☑️ 최신 JWT 라이브러리 사용
대부분의 최신 JWT 라이브러리들은 none 알고리즘을 지원하지 않지만, 일부 구 버전에서는 이를 여전히 허용하고 있으므로 항상 최신 버전으로 업데이트하는 것이 중요합니다.
☑️ JWT 만료시간 검증
JWT를 발급할 때 서비스 특성에 맞는 적절한 만료 시간(exp)을 설정하고, 서버에서는 이 값을 검증해야 합니다. 만약 요청에 만료된 토큰이 사용된 경우, 해당 요청은 즉시 차단해야 합니다. 일반적으로는 Access Token에는 짧은 만료 시간을 적용하고, 토큰 만료 시에는 Refresh Token을 통해 새로운 Access Token을 재발급 받는 구조를 사용하는 것이 권장됩니다.
☑️ 토큰 재사용(Replay Attack) 방지 전략 적용
탈취된 JWT의 재사용을 막기 위해 다음과 같은 무효화 전략을 적용할 수 있습니다. JWT의 페이로드에 TokenVersion이나 암호화된 IP 주소를 포함하고, 서버가 해당 값을 검증하는 방식입니다. TokenVersion은 비밀번호 변경, 로그아웃 등 특정 이벤트가 발생할 때 값을 증가시켜 이전 토큰을 무효화할 수 있습니다. IP 주소 검증은 등록되지 않은 IP에서의 요청을 차단해, 탈취된 토큰의 재사용을 방지할 수 있습니다.
지금까지 JWT 검증 실패로 발생할 수 있는 Broken Authentication의 발생 원인, 공격 시나리오, 대응 전략에 대해 알아봤습니다. 실제 서비스 환경에서는 소개드린 공격 시나리오 외에도 다양한 형태의 취약점이 발생하고 있습니다. 이를 예방하려면 각 API의 동작 방식 등을 세밀하게 검증해야 하지만, 모든 API를 수동으로 점검하는 데에는 현실적인 한계가 존재합니다. 스패로우는 이러한 요구를 충족하기 위해 웹 애플리케이션 취약점 동적 분석 도구인 Sparrow DAST를 제공하고 있으며, OWSAP API Top 10을 기준으로 API 취약점을 자동으로 점검할 수 있도록 지원하고 있습니다.
1. JWT (JSON Web Token): Vulnerabilities, Common Attacks and Security Best Practices / vaadata / https://www.vaadata.com/blog/jwt-json-web-token-vulnerabilities-common-attacks-and-security-best-practices/
2. Web API Security Champion Part III: Broken Object Property Level Authorization (OWASP TOP 10) / medium / https://medium.com/codex/web-api-security-champion-part-iii-broken-object-property-level-authorization-owasp-top-10-f6246273aef7
