범위를 벗어난 비트 시프트

범위를 벗어난 비트 시프트

설명

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로 전달하고 형식과 허용 범위를 검증하세요.

참조