# Auth bypass via prototype and type confusion

Token or hash checks using loose equality, inherited object keys, or overridable native prototypes

_Area: Web authentication and account takeover. Seen in 3 disclosed reports; 2 confirmed bounties: $1,270 and $1,536; latest 2023-11-30. Updated 2026-11-01._

## How it works
A credential check assumes the value it compares is a plain, trustworthy scalar. That assumption breaks in three ways: a lookup table built as an object literal inherits `Object.prototype` keys (`toString`, `constructor`, `__proto__`), so a token string naming one of those keys resolves to a function instead of "not found"; a loose `==`/`!=` comparison coerces a user string and a hash to numbers, so `"0"` equals any `0e...` magic hash; and a security check that delegates to a native binding can be fooled by mutating the binding's prototype, which the JS wrapper's own protection does not cover.

## Where it shows up
- Token/secret maps built as `{}` and queried with `in`, `obj[key]`, or truthiness, then `parseInt`'d and compared `> 0` [E1](https://bugbountylibrary.com/r/blog%3Ablog-sonarsource-com-nodebb-remote-code-execution-with-one-shot.md)
- PHP `==`/`!=` between user input and `md5`/`sha1`/`hash_hmac` output, including truncated `substr` comparisons [E3](https://bugbountylibrary.com/r/h1%3A86022.md)
- Security checks (integrity, signature, CSRF) implemented on top of a JS class that wraps C++ bindings [E2](https://bugbountylibrary.com/r/h1%3A2208860.md)
- Symbols like `kHandle` on a wrapper instance exposing the underlying binding constructor [E2](https://bugbountylibrary.com/r/h1%3A2208860.md)

## How to review
State the invariant: a credential comparison must only succeed on an exact, attacker-unknown value, and a failed lookup must be indistinguishable from "absent". Check that lookup maps are prototype-free (`Object.create(null)`, `Map`, or an explicit `hasOwnProperty` guard) and that the value is validated as a string before any numeric parse [E1](https://bugbountylibrary.com/r/blog%3Ablog-sonarsource-com-nodebb-remote-code-execution-with-one-shot.md). Check every hash/signature/CSRF comparison uses strict, constant-time equality on full-length values, never `==` and never a truncated prefix [E3](https://bugbountylibrary.com/r/h1%3A86022.md). For checks built on native bindings, confirm the binding prototype is frozen or unreachable, not just the JS wrapper's prototype [E2](https://bugbountylibrary.com/r/h1%3A2208860.md).

## How finders spotted it
- Read i18n path construction and token verification, noticing the token map was an object literal queried on inherited keys [E1](https://bugbountylibrary.com/r/blog%3Ablog-sonarsource-com-nodebb-remote-code-execution-with-one-shot.md)
- Reasoned that `crypto.Hash` protects its JS prototype but delegates to C++ bindings; inspecting an instance revealed `kHandle` and a mutable binding prototype [E2](https://bugbountylibrary.com/r/h1%3A2208860.md)
- Grepped hash comparison sites for non-strict `==`/`!=` on user-controlled strings, applying known PHP juggling behavior [E3](https://bugbountylibrary.com/r/h1%3A86022.md)

## Variants seen
- Inherited-key auth bypass yielding master API tokens [E1](https://bugbountylibrary.com/r/blog%3Ablog-sonarsource-com-nodebb-remote-code-execution-with-one-shot.md)
- Magic-hash loose comparison bypassing CSRF, API and webhook signature checks [E3](https://bugbountylibrary.com/r/h1%3A86022.md)
- Native-binding prototype override forging an integrity checksum [E2](https://bugbountylibrary.com/r/h1%3A2208860.md)

## Impact and severity
E1 chained the bypass to master tokens, admin API access and RCE, amplified by a file-read and wormable XSS [E1](https://bugbountylibrary.com/r/blog%3Ablog-sonarsource-com-nodebb-remote-code-execution-with-one-shot.md). E2 let a forged protected module inherit the trusted module's full permissions, reaching modules the entry module was denied [E2](https://bugbountylibrary.com/r/h1%3A2208860.md). E3 weakened CSRF and signature checks without demonstrated escalation [E3](https://bugbountylibrary.com/r/h1%3A86022.md). Severity rises with what the bypassed check gates and whether it chains.

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Ablog-sonarsource-com-nodebb-remote-code-execution-with-one-shot.md
- E2: https://bugbountylibrary.com/r/h1%3A2208860.md
- E3: https://bugbountylibrary.com/r/h1%3A86022.md
