# Parser differential across trust boundaries

Same bytes parsed twice with different rules; check line breaks, duplicate keys, magic-byte offsets

_Area: Web injection and code execution. Seen in 5 disclosed reports; latest 2025-03-17. Updated 2026-10-23._

## How it works
A security decision is made by one parser, but the same input is later consumed by a second parser with different semantics. The check passes on the first interpretation; the second interpretation sees something else. The broken assumption is that "the bytes I validated are the bytes that will be acted on." Any divergence — line-break handling, duplicate-key precedence, where a file type is detected, how much of the input is read, or which HTTP method fetches it — turns a passing check into a bypass.

## Where it shows up
- A validator that extracts or strips lines with a regex, then hands the remainder to a YAML parser [E1](https://bugbountylibrary.com/r/blog%3Awiz-io-blog-nuclei-signature-verification-bypass.md)
- Line-break or comment-syntax handling that differs between checker and real parser (\r vs \n) [E1](https://bugbountylibrary.com/r/blog%3Awiz-io-blog-nuclei-signature-verification-bypass.md)
- JSON validated server-side, then re-parsed client-side, with duplicate keys crossing the boundary [E3](https://bugbountylibrary.com/r/h1%3A2095061.md)
- A value blocked by a validator in one language but re-parsed by another runtime (e.g. YAML tags one evaluates and the other drops) [E2](https://bugbountylibrary.com/r/blog%3Ablog-doyensec-com-2025-03-18-exploitable-gitlab-html.md)
- File-type checks by magic bytes at fixed offsets, or parsing only a prefix, while the consumer parses the whole file [E4](https://bugbountylibrary.com/r/blog%3Ablog-doyensec-com-2025-01-09-cspt-file-upload-html.md)
- A check performed with one HTTP method (HEAD) while the body is fetched with another (GET) [E5](https://bugbountylibrary.com/r/h1%3A2106708.md)

## How to review
Identify every place the same input is parsed twice across a trust boundary. The invariant: the component enforcing the security property must parse the input with the same semantics, over the same full extent, as the component that acts on it. Check that verification covers all relevant lines/keys, not just the first [E1](https://bugbountylibrary.com/r/blog%3Awiz-io-blog-nuclei-signature-verification-bypass.md); that duplicate keys are rejected or resolved identically on both sides [E3](https://bugbountylibrary.com/r/h1%3A2095061.md); that file-type detection inspects the same bytes the consumer will interpret, not a prefix or fixed offset [E4](https://bugbountylibrary.com/r/blog%3Ablog-doyensec-com-2025-01-09-cspt-file-upload-html.md); and that the check and the fetch observe the same response [E5](https://bugbountylibrary.com/r/h1%3A2106708.md). Prefer a single parse whose result is reused.

## Variants seen
- Regex signature check vs YAML parser disagreeing on \r, plus only the first digest verified while all were stripped [E1](https://bugbountylibrary.com/r/blog%3Awiz-io-blog-nuclei-signature-verification-bypass.md)
- Ruby YAML evaluating a tag that Go yaml.v3 drops, bypassing a parent-option block [E2](https://bugbountylibrary.com/r/blog%3Ablog-doyensec-com-2025-03-18-exploitable-gitlab-html.md)
- Jackson first-duplicate-key-wins vs JavaScript last-key-wins, letting a client pass a type check with one value and act on another [E3](https://bugbountylibrary.com/r/h1%3A2095061.md)
- Magic-byte/prefix validation vs full-file JSON parsing, letting a polyglot file satisfy both a document format and JSON [E4](https://bugbountylibrary.com/r/blog%3Ablog-doyensec-com-2025-01-09-cspt-file-upload-html.md)
- HEAD-based Content-Type check vs GET fetch returning different content [E5](https://bugbountylibrary.com/r/h1%3A2106708.md)

## Why fixes fail
E5's patch validated Content-Type via HEAD but fetched via GET — a TOCTOU gap, since a server returning different responses per method bypassed it; sanitization also branched on the Accept header, which Safari sends as */*.

## Impact and severity
Consequences ranged from unverified code templates accepted by a scanner [E1](https://bugbountylibrary.com/r/blog%3Awiz-io-blog-nuclei-signature-verification-bypass.md), to arbitrary file write and RCE [E2](https://bugbountylibrary.com/r/blog%3Ablog-doyensec-com-2025-03-18-exploitable-gitlab-html.md), to spoofed server-only messages causing DoS and media swapping [E3](https://bugbountylibrary.com/r/h1%3A2095061.md), upload-filter bypass feeding client-side path traversal gadgets [E4](https://bugbountylibrary.com/r/blog%3Ablog-doyensec-com-2025-01-09-cspt-file-upload-html.md), and reflected XSS [E5](https://bugbountylibrary.com/r/h1%3A2106708.md). Severity rises when the second parser is privileged (server-side) or the bypass chains into another weakness.

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Awiz-io-blog-nuclei-signature-verification-bypass.md
- E2: https://bugbountylibrary.com/r/blog%3Ablog-doyensec-com-2025-03-18-exploitable-gitlab-html.md
- E3: https://bugbountylibrary.com/r/h1%3A2095061.md
- E4: https://bugbountylibrary.com/r/blog%3Ablog-doyensec-com-2025-01-09-cspt-file-upload-html.md
- E5: https://bugbountylibrary.com/r/h1%3A2106708.md
