암호학적으로 취약한 난수 생성기(PRNG) 사용
Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)
설명
이 취약점은 보안이 필요한 상황(토큰, 세션 ID, 비밀번호 재설정 코드 등)에서 암호학적으로 안전하지 않은 난수 생성기(PRNG)를 사용하는 경우 발생합니다. 예를 들어 Go의 math/rand는 통계적 난수에는 적합하지만, 내부 알고리즘과 시드(seed)를 추측할 수 있어 공격자가 생성된 값을 예측할 수 있습니다. 공격자는 일부 난수 값을 관찰하거나 시드를 유추해 이후 생성될 토큰·코드·키를 예측하고, 세션 탈취, 계정 탈취, 인증 우회 등을 시도할 수 있습니다.
잠재적 영향
예측 가능한 토큰·세션ID (토큰 및 세션 ID 예측 가능): 공격자가 난수 기반 토큰이나 세션 ID 값을 예측해 다른 사용자의 세션을 탈취하거나 인증을 우회할 수 있습니다.
인증·인가 우회 (인증 및 권한 우회): 비밀번호 재설정 코드, 이메일 인증 코드 등에서 약한 난수를 사용할 경우, 공격자가 무차별 대입이나 패턴 분석으로 코드를 맞춰 계정을 탈취할 수 있습니다.
암호 키 약화 (암호 키 보안 약화): 암호 키, IV, nonce 등 암호 파라미터를 취약한 PRNG로 생성하면 암호화 자체의 안전성이 크게 떨어져, 암호문 복호화나 위조가 가능해질 수 있습니다.
해결 방법
보안 용도에는 반드시
crypto/rand사용: 토큰, 세션 ID, 인증 코드, 암호 키, IV, nonce 등 보안 관련 난수는 모두crypto/rand로 생성합니다.math/rand사용 범위 제한: 게임 로직, 샘플링, 로드 밸런싱 같은 비보안(non-security) 용도에만math/rand를 사용합니다.난수 길이 충분히 확보: 토큰·코드를 만들 때는 최소 128bit(16byte) 이상 난수를 사용해 무차별 대입 공격을 어렵게 만듭니다.
공통 유틸 함수 작성: 팀 차원에서
GenerateSecureToken등 공용 secure-random 헬퍼 함수를 만들고, 모든 서비스에서 이것만 사용하도록 가이드합니다.코드 리뷰 체크 리스트에 포함: PRNG 사용 시
crypto/rand인지, 보안 목적에 적절한 길이와 인코딩(예: hex, base64)을 사용하는지 확인합니다.
취약한 코드 및 안전한 코드 예시
취약한 코드
안전한 코드
설명:
취약한 코드: 위 비준수 코드에서는 비밀번호 재설정 토큰을 생성하는 데
math/rand를 사용합니다.math/rand는 시드를 알거나 추측할 수 있으면 생성되는 난수 순서를 모두 예측할 수 있는 비암호학적 PRNG입니다. 시드로 현재 시간(time.Now().UnixNano())을 사용하기 때문에, 공격자는 요청 시간을 대략적으로 알고 있다면 같은 시드로 토큰을 재현하거나 주변 값을 시도해 실제 토큰을 맞출 수 있습니다. 따라서 토큰, 세션 ID 같은 보안 민감 값에math/rand를 사용하는 것은 취약합니다.안전한 코드: 준수 코드에서는 Go의
crypto/rand패키지의rand.Read를 사용해 암호학적으로 안전한 난수를 생성합니다. 이 난수는 운영체제의 CSPRNG(cryptographically secure PRNG)를 기반으로 하며, 외부에서 시드나 내부 상태를 현실적으로 예측할 수 없습니다. 또한 충분한 길이(128비트)를 사용하여 무차별 대입 공격을 어렵게 만들고,hex.EncodeToString으로 안전하게 문자열로 변환해 토큰으로 사용합니다. 이로 인해 공격자가 토큰 값을 예측하거나 재현하기 매우 어려워져 취약점이 완화됩니다.
참조
Last updated