From 53092846196f273c5bb3234d5bb5684ff2952237 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Tue, 5 May 2026 07:49:38 +0000 Subject: [PATCH] Add content from: $170k in Bypasses: The Vercel React2Shell Challenge --- .../proxy-waf-protections-bypass.md | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/pentesting-web/proxy-waf-protections-bypass.md b/src/pentesting-web/proxy-waf-protections-bypass.md index 467864df568..e61f60861e2 100644 --- a/src/pentesting-web/proxy-waf-protections-bypass.md +++ b/src/pentesting-web/proxy-waf-protections-bypass.md @@ -106,6 +106,43 @@ Connection: close\r\n It was possible to bypass AWS WAF because it wouldn't understand that the next line is part of the value of the header while the NODEJS server did (this was fixed). +## Multipart / parser-differential WAF bypasses + +Some emergency WAF rules for parser-driven bugs try to **parse `multipart/form-data` themselves** and then scan only the reconstructed fields. This is fragile: if the WAF and the backend do **not** implement the **same grammar**, the WAF can inspect a harmless interpretation while the backend rebuilds the real payload. Treat this as a **grammar un-equivalence** problem, not as pure signature evasion. + +This is especially relevant in exploit chains such as **React2Shell**, where the malicious server-side object graph can stay unchanged while only the **HTTP transport syntax** is mutated until the WAF and the origin disagree. + +### High-value parser differential checks + +- **Top-level `Content-Type` parsing**: duplicate `boundary=` parameters, quoted vs unquoted values, spaces, escapes, RFC 5987 parameters, multiple `Content-Type` headers, case sensitivity, invalid/non-UTF8 bytes. +- **Multipart framing**: garbage before/after the first boundary, `\r\n` vs `\n`, large body handling, duplicate field names, malformed closing markers such as ``--boundary-- ``. +- **Per-part headers**: duplicate `Content-Type`, `Content-Disposition` quirks (`filename`, `filename*=`), per-part charsets such as `utf16le` / `ucs2`, duplicate sub-headers, `Content-Transfer-Encoding`. + +### Exploitable patterns + +- **Duplicate parameter precedence mismatch**: if the WAF uses the last `boundary=` but the backend uses the first one, the WAF can parse an empty body while the backend parses the attacker-controlled parts. +- **Fail-open parser errors**: if malformed headers or invalid octets make the WAF parser error and the request is still forwarded, inspection is effectively disabled. +- **Per-part charset decoding gaps**: if the backend honors `Content-Type: text/plain; charset=utf16le` (or `ucs2`) inside a multipart part while the WAF scans raw bytes, blocked markers such as `:constructor` can be hidden in the encoded body. `busboy`, for example, maps `utf16le` / `ucs2` to a UTF-16 decoder. +- **Duplicate multipart sub-headers**: duplicated `Content-Type` headers inside the same part can create a second precedence mismatch where the WAF sees `charset=utf8` but the backend honors the first `charset=utf16le`. +- **Boundary termination quirks**: if the WAF accepts `--boundary-- ` as the final marker but the backend rejects the trailing whitespace, the WAF stops scanning too early and the backend keeps parsing later parts. + +### Testing workflow + +1. Find or build an endpoint that shows how the **backend parser** reconstructed each multipart field. +2. Keep the **backend payload** identical and mutate only the **transport grammar**. +3. Diff the WAF decision against backend parsing while fuzzing duplicate parameters, duplicate headers, malformed octets, part charsets, and closing-boundary syntax. +4. Treat **parse error => allow** as a critical finding and validate first with safe marker strings before replaying the real exploit payload. + +These ambiguities often overlap with: + +{{#ref}} +http-request-smuggling/README.md +{{#endref}} + +{{#ref}} +file-upload/README.md +{{#endref}} + ## Generic WAF bypasses ### Request Size Limits @@ -243,11 +280,13 @@ data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascri ## References - [https://blog.hackcommander.com/posts/2025/12/28/turning-a-harmless-xss-behind-a-waf-into-a-realistic-phishing-vector/](https://blog.hackcommander.com/posts/2025/12/28/turning-a-harmless-xss-behind-a-waf-into-a-realistic-phishing-vector/) +- [https://www.hacktron.ai/blog/react2shell-vercel-waf-bypass](https://www.hacktron.ai/blog/react2shell-vercel-waf-bypass) - [https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) - [https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) - [https://www.youtube.com/watch?v=0OMmWtU2Y_g](https://www.youtube.com/watch?v=0OMmWtU2Y_g) - [https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization) - [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/) +- [https://github.com/mscdex/busboy/blob/6b3dcf69d38c1a8d53a0b3e4c88ba296f6c91525/lib/utils.js#L403-L406](https://github.com/mscdex/busboy/blob/6b3dcf69d38c1a8d53a0b3e4c88ba296f6c91525/lib/utils.js#L403-L406) {{#include ../banners/hacktricks-training.md}}