설명
JWT의 대칭 서명 비밀 키를 소스 코드에 직접 저장하면 저장소나 배포 파일을 읽을 수 있는 사람이 키를 얻을 수 있습니다. 이 키를 신뢰하는 시스템에서는 공격자가 토큰을 위조해 인증이나 권한 검사를 우회할 수 있습니다.
잠재적 영향
- 유출된 키로 서명한 JWT가 수락되면 다른 사용자를 가장하거나 허용되지 않은 권한을 얻을 수 있습니다.
- 그 권한 범위에서 데이터를 읽거나 변경할 수 있으며, 키 교체와 기존 토큰 무효화가 필요할 수 있습니다.
해결 방법
- 비밀 키를 코드에 저장하지 말고 접근이 제한된 비밀 저장소나 배포 환경에서 공급하세요.
- 충분한 길이의 암호학적 난수 키를 사용하고, 환경 변수나 구성 파일의 접근 권한과 로그 노출도 관리하세요.
- 노출된 키는 교체하고 기존 키로 만든 토큰을 더 이상 신뢰하지 않도록 하세요. 비밀 값이 없을 때는 토큰을 발급하지 마세요.
예시
jose 1.28.2의 JWT.sign을 사용하는 기존 코드의 발췌입니다. 현재 버전의 API와는 다르므로 새 코드에는 지원되는 버전의 SignJWT API를 사용하세요. 예시는 키 공급 방식만 비교하며, 알고리즘·발급자·대상·만료 정책은 별도로 설정해야 합니다.
변경 전
javascript
const { JWT } = require('jose')
const payload = {foo: 'bar'}
// 취약: 비밀키가 소스코드 내에 하드코딩됨
const token = JWT.sign(payload, 'my-secret-key')
변경 후
javascript
const { JWT } = require('jose')
const payload = {foo: 'bar'}
// 안전: 비밀키를 환경변수에서 불러옴
const secret = process.env.JWT_SECRET
if (!secret) {
throw new Error("JWT_SECRET is required")
}
const token = JWT.sign(payload, secret)
설명:
- 변경 전: 비밀키('my-secret-key')가 코드에 직접 노출되어 있습니다. 코드를 열람한 공격자가 토큰을 위조하고, 이 키를 신뢰하는 시스템에서 허용되지 않은 접근을 시도할 수 있습니다.
- 변경 후: 비밀키를 환경변수(process.env.JWT_SECRET)에서 불러오도록 하여, 코드 자체에 키를 저장하지 않고, 값이 없으면 발급을 중단합니다. 공급한 키의 난수 품질과 저장 환경 보호도 필요합니다. 또한, 운영 환경별로 다른 키를 사용할 수 있어 보안 관리가 더 수월합니다.