## TL;DR

`detect-object-injection` flags `obj[userInput]` because attacker-controlled keys can hit prototype properties. Replace the object with a `Map`, or validate the key against an explicit allowlist before indexing.

## Error

```text
src/auth.js:88:5: error  Generic Object Injection Sink  security/detect-object-injection
```

## Steps

1. Find the flagged access: an expression like `config[name]` where `name` comes from outside the function. Expected: the sink line the rule reports.
2. If the keys are a fixed set, switch to a `Map` or a lookup with an allowlist check: `if (!ALLOWED.has(name)) throw ...`. Expected: the rule no longer fires because the sink is gone.
3. If dynamic keys are genuinely needed, guard with `Object.prototype.hasOwnProperty.call(obj, name)`. Expected: prototype pollution is blocked; the rule may still flag  -  then disable it for that line with a comment.
4. Re-run eslint on the file. Expected: no `security/detect-object-injection` errors.

## When to use

- eslint-plugin-security reports `security/detect-object-injection` on the PR.
- The flagged access uses a dynamic key.

## When not to use

- A different security rule fires (e.g. detect-eval-with-expression)  -  fix that rule instead.
- The key is a compile-time constant; the rule may be misfiring on your config  -  check rule options first.

## Tool compatibility

- eslint-plugin-security 1.7+.
- Any ESLint 7/8/9 setup.

## Variant phrasings

### detect-object-injection on `obj[key] = value`

Same fix: Map.set or allowlist the key before assignment.

### Rule fires on safe code

Scope a `// eslint-disable-next-line security/detect-object-injection` with a comment explaining why the key is safe.

## Why it happens

Indexing an object with an attacker-controlled string can reach `__proto__` or `constructor`, enabling prototype pollution. The rule flags every dynamic index as a potential sink because it cannot prove the key is safe.

## Edge cases

- `Map` is the cleanest fix but changes iteration semantics; check for `Object.keys`/`for...in` usage before converting.
- Allowlist checks belong as close to the sink as possible, not three calls up the stack.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_egxoXWW5cT52sN0JQbXTuQ
