Out-of-range bit shift

Out-of-range bit shift

Description

JavaScript bit shifts on Number values operate on 32-bit integers and use only the lower five bits of the right operand. Shift counts of 32 or more, or negative counts, can therefore produce a result different from the intended arithmetic. This is a correctness issue; its security impact depends on how the result affects permissions or resource handling.

Potential impact

  • Bit masks or flags may evaluate incorrectly.
  • Incorrect lengths, sizes or indices may cause improper resource handling.
  • Calculations intended to use 64-bit or larger integers may instead follow 32-bit shift rules.

Remediation

  • Restrict Number shift counts to 0 through 31.
  • Use BigInt and explicit range checks for integer operations wider than 32 bits.
  • Test constants used in masks and size calculations against the intended result.

Examples

Before

javascript
const ADMIN_MASK = 1 << 32;

function hasAdmin(flags) {
  return (flags & ADMIN_MASK) !== 0;
}

After

javascript
const ADMIN_MASK = 1n << 32n;

function hasAdmin(flags) {
  return (BigInt(flags) & ADMIN_MASK) !== 0n;
}

1 << 32 equals 1 << 0, or 1, instead of setting the intended 33rd bit. The second excerpt uses BigInt to preserve that bit position. Converting a large value to Number first can lose precision: supply flags as an exact integer string or a BigInt, and validate its format and permitted range.

References