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
Numbershift counts to 0 through 31. - Use
BigIntand 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.