설명
JavaScript의 Number 비트 시프트 연산은 32비트 정수로 연산하며 오른쪽 피연산자의 하위 5비트만 사용합니다. 따라서 32 이상 또는 음수 시프트 값은 작성자가 의도한 산술과 다르게 동작할 수 있습니다. 이는 계산 정확성 문제이며, 보안상 영향은 그 결과를 권한이나 리소스 처리에 어떻게 사용하는지에 따라 달라집니다.
잠재적 영향
- 비트 마스크나 플래그 계산이 의도와 다르게 평가될 수 있습니다.
- 길이, 크기, 인덱스 계산 오류로 잘못된 리소스 처리가 발생할 수 있습니다.
- 코드 작성자가 기대한 64비트 이상 정수 연산이 실제로는 32비트 시프트 규칙으로 축소될 수 있습니다.
해결 방법
Number의 시프트 값은 0 이상 31 이하로 제한하세요.- 32비트를 초과하는 정수 연산이 필요하면
BigInt와 명시적인 범위 검사를 사용하세요. - 마스크나 크기 계산에 사용하는 상수는 테스트로 의도한 결과를 확인하세요.
예시
변경 전
javascript
const ADMIN_MASK = 1 << 32;
function hasAdmin(flags) {
return (flags & ADMIN_MASK) !== 0;
}
변경 후
javascript
const ADMIN_MASK = 1n << 32n;
function hasAdmin(flags) {
return (BigInt(flags) & ADMIN_MASK) !== 0n;
}
설명:
- 변경 전:
1 << 32는 32비트 시프트 규칙 때문에 의도한 33번째 비트가 아니라1 << 0과 같은 값인1이 됩니다. - 변경 후: 32비트를 넘는 비트 연산에
BigInt를 사용해 의도한 비트 위치를 명확히 계산합니다. 큰 값을 먼저Number로 변환하면 정밀도를 잃을 수 있으므로,flags는 정확한 정수 문자열이나BigInt로 전달하고 형식과 허용 범위를 검증하세요.