Unguarded for…​in

ID

javascript.guard_for_in

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

JavaScript

Tags

best-practice, reliability

Description

Reports for …​ in loops whose body does not start with an if that filters by Object.prototype.hasOwnProperty (or one of its safer shapes). A bare for…​in iterates over every enumerable property of the object — including those inherited from the prototype chain.

Rationale

for…​in walks the prototype chain. Without an own-property guard:

  • properties added to Object.prototype (or any ancestor) by other code leak into the loop body,

  • the loop is sensitive to the iteration order of inherited properties, which is implementation-defined,

  • the bug is invisible until a library or polyfill modifies a shared prototype.

// Bad - iterates inherited keys too
for (const key in user) {
  process(user[key]);
}

Remediation

Use one of the standard guards, or switch to Object.keys(…​) / Object.entries(…​) which already skip inherited properties.

// Good - explicit guard
for (const key in user) {
  if (Object.hasOwn(user, key)) {
    process(user[key]);
  }
}

// Good - use Object.keys instead
for (const key of Object.keys(user)) {
  process(user[key]);
}