@gpzhang2001/sharpkit-skills 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +12 -0
  3. package/THIRD_PARTY_NOTICES.md +48 -0
  4. package/lib/index.d.ts +2027 -0
  5. package/lib/index.d.ts.map +1 -0
  6. package/lib/index.js +70 -0
  7. package/lib/index.js.map +1 -0
  8. package/package.json +46 -0
  9. package/skills/analysis/counterevidence.md +185 -0
  10. package/skills/analysis/fix_verification.md +129 -0
  11. package/skills/analysis/severity_calibration.md +130 -0
  12. package/skills/analysis/source_aware_discovery.md +211 -0
  13. package/skills/cloud/aws.md +231 -0
  14. package/skills/cloud/azure.md +262 -0
  15. package/skills/cloud/gcp.md +194 -0
  16. package/skills/cloud/kubernetes.md +223 -0
  17. package/skills/coordination/root_agent.md +105 -0
  18. package/skills/coordination/source_aware_whitebox.md +47 -0
  19. package/skills/custom/api_spec_testing.md +61 -0
  20. package/skills/custom/dependency_cve_scanning.md +341 -0
  21. package/skills/custom/npx_confusion.md +233 -0
  22. package/skills/custom/source_aware_sast.md +192 -0
  23. package/skills/frameworks/django.md +214 -0
  24. package/skills/frameworks/fastapi.md +191 -0
  25. package/skills/frameworks/nestjs.md +225 -0
  26. package/skills/frameworks/nextjs.md +228 -0
  27. package/skills/protocols/graphql.md +276 -0
  28. package/skills/protocols/oauth.md +185 -0
  29. package/skills/reconnaissance/asset_discovery.md +150 -0
  30. package/skills/reconnaissance/infrastructure_lifecycle.md +226 -0
  31. package/skills/scan_modes/deep.md +164 -0
  32. package/skills/scan_modes/diff.md +86 -0
  33. package/skills/scan_modes/quick.md +68 -0
  34. package/skills/scan_modes/standard.md +99 -0
  35. package/skills/technologies/active_directory.md +233 -0
  36. package/skills/technologies/auth0.md +188 -0
  37. package/skills/technologies/electron_desktop_apps.md +181 -0
  38. package/skills/technologies/firebase.md +263 -0
  39. package/skills/technologies/grafana_prometheus.md +189 -0
  40. package/skills/technologies/llm_applications.md +257 -0
  41. package/skills/technologies/supabase.md +268 -0
  42. package/skills/tooling/agent_browser.md +551 -0
  43. package/skills/tooling/ffuf.md +72 -0
  44. package/skills/tooling/httpx.md +82 -0
  45. package/skills/tooling/hurl.md +99 -0
  46. package/skills/tooling/hypothesis.md +100 -0
  47. package/skills/tooling/katana.md +102 -0
  48. package/skills/tooling/naabu.md +68 -0
  49. package/skills/tooling/nmap.md +66 -0
  50. package/skills/tooling/nuclei.md +67 -0
  51. package/skills/tooling/python.md +109 -0
  52. package/skills/tooling/semgrep.md +72 -0
  53. package/skills/tooling/sqlmap.md +67 -0
  54. package/skills/tooling/subfinder.md +66 -0
  55. package/skills/vulnerabilities/agentic_system_security.md +207 -0
  56. package/skills/vulnerabilities/argument_injection.md +157 -0
  57. package/skills/vulnerabilities/authentication_jwt.md +166 -0
  58. package/skills/vulnerabilities/broken_function_level_authorization.md +154 -0
  59. package/skills/vulnerabilities/browser_security.md +192 -0
  60. package/skills/vulnerabilities/business_logic.md +178 -0
  61. package/skills/vulnerabilities/csrf.md +198 -0
  62. package/skills/vulnerabilities/header_injection.md +216 -0
  63. package/skills/vulnerabilities/http_request_smuggling.md +255 -0
  64. package/skills/vulnerabilities/idor.md +217 -0
  65. package/skills/vulnerabilities/information_disclosure.md +187 -0
  66. package/skills/vulnerabilities/insecure_deserialization.md +210 -0
  67. package/skills/vulnerabilities/insecure_file_uploads.md +194 -0
  68. package/skills/vulnerabilities/llm_prompt_injection.md +187 -0
  69. package/skills/vulnerabilities/mass_assignment.md +153 -0
  70. package/skills/vulnerabilities/nosql_injection.md +288 -0
  71. package/skills/vulnerabilities/open_redirect.md +165 -0
  72. package/skills/vulnerabilities/path_traversal_lfi_rfi.md +218 -0
  73. package/skills/vulnerabilities/prototype_pollution.md +142 -0
  74. package/skills/vulnerabilities/race_conditions.md +181 -0
  75. package/skills/vulnerabilities/rce.md +250 -0
  76. package/skills/vulnerabilities/semantic_confusion.md +189 -0
  77. package/skills/vulnerabilities/sql_injection.md +190 -0
  78. package/skills/vulnerabilities/ssrf.md +186 -0
  79. package/skills/vulnerabilities/ssti.md +270 -0
  80. package/skills/vulnerabilities/subdomain_takeover.md +167 -0
  81. package/skills/vulnerabilities/weak_password_detection.md +200 -0
  82. package/skills/vulnerabilities/xss.md +206 -0
  83. package/skills/vulnerabilities/xxe.md +223 -0
  84. package/src/index.ts +89 -0
@@ -0,0 +1,216 @@
1
+ ---
2
+ name: header-injection
3
+ description: HTTP header injection testing covering CRLF / response splitting, cache poisoning, Host-header confusion, cookie fixation, and proxy / forwarding header smuggling
4
+ ---
5
+
6
+ # HTTP Header Injection
7
+
8
+ Header injection turns user input into protocol-level control: response splitting, cache poisoning, session fixation, authentication bypass, and downstream parser confusion can trace back to a server-controlled header value that was not normalized. The bug usually lives in middle layers — frameworks that copy a request value into a response header, proxies that trust forwarded headers, caches keyed on something the attacker influences. Impact depends on which downstream component consumes the injected field and how.
9
+
10
+ ## Attack Surface
11
+
12
+ **Input shapes that reach headers**
13
+ - Query/body/path values echoed into `Set-Cookie`, `Location`, `Content-Type`, `Content-Disposition`, `Link`, custom `X-*`
14
+ - Request headers re-emitted into responses (Referer, User-Agent, X-Forwarded-*, custom correlation IDs)
15
+ - Webhook / callback flows where the server constructs outbound requests using user-supplied URLs (Host, Referer)
16
+ - Outbound email headers (To/From/Subject) populated from user input
17
+
18
+ **Code patterns that enable injection**
19
+ - Direct concatenation of user input into header values without CR/LF stripping
20
+ - Frameworks that accept header values as strings and serialize verbatim (no normalization)
21
+ - Proxy chains trusting `X-Forwarded-*` / `Forwarded` / `X-Real-IP` set by an upstream that anyone can spoof
22
+ - `X-HTTP-Method-Override` and similar method-shaping headers respected past auth layers
23
+
24
+ **Transports and parser layers**
25
+ - HTTP/1.0, HTTP/1.1, HTTP/2, HTTP/3 each parse framing differently
26
+ - CDN / reverse proxy → application server (where each side may disagree on framing)
27
+ - Chunked transfer encoding boundaries and multipart/form-data delimiters
28
+
29
+ ## High-Value Targets
30
+
31
+ - Password-reset and account-recovery flows (Host header determines the link sent to the user)
32
+ - OAuth / SSO redirect endpoints (`Location`, `redirect_uri` echoes)
33
+ - Auth gateways that trust `X-Forwarded-For` / `X-Real-IP` for IP allowlists or rate limits
34
+ - CDN / WAF caches (poisoning a public cache with a per-user response)
35
+ - Multi-tenant routing keyed on Host or `X-Tenant-Id`
36
+ - File-download endpoints (`Content-Disposition` filename derived from user input)
37
+ - Outbound notification / email systems where user input lands in the message header
38
+
39
+ ## Reconnaissance
40
+
41
+ ### Header Inventory
42
+
43
+ - Enumerate every response header that varies with input — flip query / body / cookie values and diff `Set-Cookie`, `Location`, `Content-Type`, `Content-Disposition`, `ETag`, `Vary`, custom `X-*`
44
+ - For each varying header, identify the source field (user-controlled vs. server-derived)
45
+ - Look for request headers reflected into responses (Referer in error pages, User-Agent in correlation IDs, X-Forwarded-Host echoed back)
46
+
47
+ ### CR/LF and Whitespace Variants
48
+
49
+ - Bare LF (`%0a`), bare CR (`%0d`), CRLF (`%0d%0a`)
50
+ - Double encoding (`%250d%250a`) for WAFs that decode once
51
+ - Overlong UTF-8 of CR/LF (`%c0%8d`, `%c0%8a`) — invalid per spec but accepted by some parsers
52
+ - Unicode line/paragraph separators (`%e2%80%a8` U+2028, `%e2%80%a9` U+2029) — sometimes folded to LF by intermediaries
53
+ - Tab (`%09`) — RFC 7230 allows tabs in field values, useful for sneaking past simple `\s+` filters
54
+ - Null byte (`%00`) — can truncate the header value in some parsers
55
+
56
+ ### Parser and Server Fingerprinting
57
+
58
+ - `Server`, `Via`, `X-Powered-By`, `X-AspNet-Version`, `X-Served-By`, `CF-Ray`, `X-Amzn-RequestId` reveal the stack
59
+ - `Vary`, `Age`, `X-Cache`, `CF-Cache-Status` reveal caching layer and key composition
60
+ - Same payload over HTTP/1.1 vs HTTP/2 vs chunked — diff status, headers, body length to map parsing differences
61
+ - Compare `Host` and `X-Forwarded-Host` precedence: send both with different values and observe which wins in redirects, links, log entries
62
+
63
+ ## Key Vulnerabilities
64
+
65
+ ### CRLF Response Splitting
66
+
67
+ Inject `\r\n\r\n` to terminate the current response and prepend a second attacker-controlled response. Cache or downstream proxy may key on the first response and serve the second to other users.
68
+
69
+ ```
70
+ GET /redirect?to=foo%0d%0aSet-Cookie:%20admin=1%0d%0a%0d%0a<html>poisoned</html> HTTP/1.1
71
+ ```
72
+
73
+ Request smuggling is a separate request-boundary vulnerability involving disagreement between two HTTP parsers, not simply response header injection at the request layer. Load `http_request_smuggling` when conflicting lengths, transfer coding, HTTP/2 downgrades, or connection desynchronization are in scope.
74
+
75
+ ### Cache Poisoning
76
+
77
+ - **Unkeyed input → keyed response**: input that influences the response body but not the cache key (an `X-Forwarded-Host` echoed in a link, an unkeyed query parameter reflected in HTML)
78
+ - **`Vary` manipulation**: inject a `Vary` header to over-fragment the cache (DoS-flavored) or under-fragment it (cross-user serving)
79
+ - **`X-Forwarded-Proto` / `X-Forwarded-Host` poisoning**: backend uses these to build canonical URLs in the response; CDN caches the response with attacker-controlled links
80
+ - **`Cache-Control` injection**: flip `private` to `public` (or vice versa) to change cache eligibility; inject `max-age=999999` for persistent poisoning, or `max-age=0` / `no-cache` to flush — `Age` is generated by the cache itself and isn't a freshness control, don't bother with it
81
+ - **Web cache deception**: trick the cache into storing an authenticated response at a public-looking URL (`/account/profile.css`) by appending a cacheable extension
82
+
83
+ ### Host Header Confusion
84
+
85
+ Backends often trust `Host` (or `X-Forwarded-Host`) when constructing absolute URLs — password reset emails, OAuth `redirect_uri`, canonical link tags. Sending a forged Host produces a reset link pointing at attacker-controlled infrastructure that still carries the victim's reset token.
86
+
87
+ ```
88
+ POST /password-reset HTTP/1.1
89
+ Host: attacker.tld
90
+ ```
91
+
92
+ Also test: precedence between `Host` and `X-Forwarded-Host`, IPv6 bracketing (`Host: [::1]:80`), trailing dot (`Host: example.com.`), and port confusion (`Host: example.com:@attacker.tld`).
93
+
94
+ ### Cookie / Set-Cookie Manipulation
95
+
96
+ - Inject `Domain=.example.com` or `Path=/` to widen scope of an attacker-set cookie
97
+ - Inject `SameSite=None; Secure` to allow cross-site inclusion
98
+ - Inject `Max-Age=999999999` for persistence, or `Max-Age=-1` to nuke the victim's session
99
+ - Inject a cookie with the same name as a real session cookie — precedence rules let a same-domain attacker shadow it (cookie tossing)
100
+ - Reflected cookie XSS: if a cookie value is later rendered unescaped in HTML, the injection point is the header but the sink is the page
101
+
102
+ ### Proxy and Forwarding Header Spoofing
103
+
104
+ The `X-Forwarded-*` family is informational — there is no protocol guarantee about who set them. Any application that trusts them past the boundary it controls is exploitable.
105
+
106
+ - `X-Forwarded-For: 127.0.0.1` to bypass IP allowlists or rate limits keyed on client IP
107
+ - `X-Forwarded-Proto: https` to satisfy "HTTPS-only" checks while still using HTTP
108
+ - `X-Forwarded-Host: attacker.tld` for the Host-confusion variants above
109
+ - `X-Real-IP`, `Client-IP`, `True-Client-IP`, `CF-Connecting-IP`, `Forwarded` (RFC 7239) — same trust class under different conventions; select evidence-supported variants for the observed proxy/CDN stack
110
+ - `X-Original-URL` / `X-Rewrite-URL` (IIS, ASP.NET) — server-side URL rewriting after auth check, classic admin-panel auth bypass
111
+
112
+ ### Content-Type / Encoding Confusion
113
+
114
+ - Inject `Content-Type: text/html` into an endpoint that returned JSON; browsers may sniff and render → XSS
115
+ - Inject `Content-Disposition: inline` to switch a download into in-page rendering
116
+ - *Absence* of `X-Content-Type-Options: nosniff` is what enables the sniffing attacks above; the header is a hardening control, not an attack surface — but if a server sets it inconsistently across endpoints, target the ones that don't
117
+ - Compare MIME validators with browser parsing of duplicate or comma-joined `Content-Type` values. Record first/last valid member behavior and invalid-parameter recovery for each consumer.
118
+
119
+ ### Internal Redirect and Handler Confusion
120
+
121
+ - Determine whether CGI/FastCGI/WSGI-style response headers can trigger an internal redirect instead of an external response.
122
+ - Trace which request fields survive the redirect: content type, handler, method, authorization result, path, and environment.
123
+ - Test whether response metadata is reused as an internal handler, proxy target, template type, or interpreter selection.
124
+ - Compare direct access controls with the internally dispatched resource. A protected URL may be unreachable directly while the same handler is invokable through a clean internal redirect.
125
+ - Treat CRLF injection and response-controlling SSRF as possible inputs to this chain, then validate handler selection before using a privileged handler.
126
+
127
+ ### XSS via Response Headers
128
+
129
+ - `Location: javascript:alert(1)` if redirect target is reflected unescaped (browsers usually block, but some legacy clients and Electron-style hosts don't)
130
+ - `Location: data:text/html,<script>alert(1)</script>` — same caveat
131
+ - `Refresh: 0; url=javascript:alert(1)` — the legacy `Refresh` header is a JavaScript-free meta-refresh equivalent
132
+ - Reflected request header XSS: `Referer` echoed into a custom error page, `User-Agent` echoed into a debug header — combine CRLF injection with a body-injection sink
133
+
134
+ ### Open Redirect via Headers
135
+
136
+ - `Location` is the obvious one
137
+ - `Refresh: 0; url=https://attacker.tld` — bypasses some `Location`-only filters
138
+ - `Link: <https://attacker.tld>; rel="canonical"` — usually informational but consumed by SEO tooling and some clients
139
+ - `X-Accel-Redirect: /internal/file` (Nginx) — if user input reaches this, internal-only files become accessible
140
+
141
+ ### HTTP/2 Pseudo-Header and Frame Confusion
142
+
143
+ - HTTP/2 splits headers into pseudo-headers (`:method`, `:path`, `:authority`, `:scheme`) and regular fields. Servers downgrading to HTTP/1.1 sometimes mishandle pseudo-header values, enabling smuggling across the H2 → H1 boundary.
144
+ - HTTP/2 lowercases header names; an upstream H1 filter that's case-sensitive may miss a lowercase variant that the H2 backend then accepts.
145
+ - HEADERS / CONTINUATION frame splitting: payload spans frames, intermediaries differ on whether they reassemble before applying filters.
146
+
147
+ ## Bypass Techniques
148
+
149
+ **Encoding**
150
+ - URL-encode (`%0d%0a`) and double-encode (`%250d%250a`) for WAFs that decode the wrong number of times
151
+ - Mix encodings within one payload: `%0d%0A`, `%0D\n`, alternating case
152
+ - Newline-equivalent Unicode: U+2028 / U+2029 (sometimes folded to LF), overlong UTF-8 of CR/LF
153
+
154
+ **Header normalization edges**
155
+ - Leading / trailing whitespace and tabs in header names and values
156
+ - Header folding (obs-fold per RFC 7230 — formally obsolete, but some parsers still accept continuation lines starting with whitespace)
157
+ - Duplicate headers — RFC says join with `,`; in practice servers pick first, last, or differ from the proxy in front of them
158
+
159
+ **Method and method-override**
160
+ - `X-HTTP-Method-Override: PUT` (and `X-Method-Override`, `X-HTTP-Method`) to reach state-changing handlers when the framework consults the override before applying method-based authorization
161
+ - Effective from server-side or non-browser clients (curl, internal tooling, server-to-server proxies); from a browser the header is non-safelisted and triggers a CORS preflight, so it isn't a CSRF primitive on its own
162
+
163
+ **Header name games**
164
+ - Case mangling for filters that key off exact casing
165
+ - Null byte truncation in header name (`X-Forwarded-For\x00Evil`) on parsers that stop at NUL
166
+
167
+ ## Testing Methodology
168
+
169
+ 1. **Inventory varying headers** — enumerate every response header whose value moves with input
170
+ 2. **Probe CR/LF normalization** — inject `%0d%0a` (and the encoding variants) into each varying header source; observe whether the second line lands as a real header
171
+ 3. **Test Host / X-Forwarded-Host** — submit a password-reset or any link-generating flow with attacker-controlled Host; confirm the link in the response or follow-up email
172
+ 4. **Probe forwarding headers** — spoof `X-Forwarded-For`, `X-Real-IP`, `True-Client-IP`, `CF-Connecting-IP` against IP-restricted endpoints (admin, rate-limited)
173
+ 5. **Test cache key / response content split** — find inputs that change the body but not the cache key; confirm a second request from a different session sees the poisoned response
174
+ 6. **Test method override** — `X-HTTP-Method-Override` paired with state-changing endpoints reachable via POST or GET
175
+ 7. **Route framing discrepancies** — if evidence indicates request-boundary disagreement, switch to `http_request_smuggling`
176
+ 8. **Cross-protocol** — replay payloads over HTTP/1.1 and HTTP/2; diff behavior
177
+ 9. **Trace internal reprocessing** — where response headers can cause subrequests/internal redirects, diff retained fields and final handler selection
178
+
179
+ ## Validation
180
+
181
+ 1. Show two distinct users (or sessions) receiving content keyed on attacker-supplied header — proves cache poisoning
182
+ 2. Capture a password-reset / OAuth link pointing at attacker-controlled host — proves Host injection
183
+ 3. Demonstrate the same endpoint returning different auth decisions with and without a forged forwarding header
184
+ 4. For response splitting: show a downstream cache or proxy serving the injected second response to an unrelated request
185
+ 5. All findings should produce a durable artifact (cached response, sent email, log entry, session change) — transient anomalies are not validation
186
+ 6. For internal redirects, capture both the injected response metadata and the final internally selected route/handler
187
+
188
+ ## False Positives
189
+
190
+ - Headers that vary by input but are correctly keyed in the cache (intentional personalization, Vary set correctly)
191
+ - `X-Forwarded-*` reflected back but only used for logging — not a security boundary, may not be exploitable
192
+ - Browsers blocking `Location: javascript:` or `Location: data:` — capability exists in the protocol but most modern browsers refuse to navigate
193
+ - CRLF appearing in response headers but stripped by an outer proxy before reaching any client or cache
194
+
195
+ ## Impact
196
+
197
+ - Cross-user cache poisoning (defacement, XSS, account takeover via cached auth response)
198
+ - Account takeover via Host-confused password-reset / OAuth flows
199
+ - Auth bypass on endpoints trusting forwarding headers
200
+ - Session fixation and cookie tossing leading to account hijack
201
+ - Open redirect for phishing / OAuth `redirect_uri` abuse
202
+ - WAF / detection bypass via header-name and encoding tricks
203
+
204
+ ## Pro Tips
205
+
206
+ 1. The fastest win is usually Host / `X-Forwarded-Host` in a password-reset or OAuth flow — try first, costs one request
207
+ 2. For cache poisoning, find the *unkeyed* input first (header that influences body but not cache key); the rest follows
208
+ 3. `X-HTTP-Method-Override` is high-yield against backends that route on it before checking method-based auth — most useful from server-side / non-browser callers (it triggers CORS preflight in a browser, so not a CSRF primitive)
209
+ 4. If a header test exposes message-boundary disagreement, switch to the dedicated request-smuggling workflow and identify the proxy → backend pair
210
+ 5. `X-Original-URL` / `X-Rewrite-URL` against IIS / ASP.NET admin endpoints is still a high-yield bypass
211
+ 6. Before claiming a CRLF win, verify the second line landed as a real header in the cache or downstream consumer — many servers strip CRLF silently
212
+ 7. Outbound email flows are a separate but related surface — user input flowing into SMTP headers (To, Cc, Subject, Reply-To) is its own injection class with the same root cause
213
+
214
+ ## Summary
215
+
216
+ Header injection is fundamentally a normalization failure: somewhere on the request → response path, user input reached a header value without CR/LF stripping or proper escaping. The impact tiers up from open redirect to cache poisoning to request smuggling depending on which downstream component trusts the resulting header. Audit every header whose value moves with input, and treat every `X-Forwarded-*` / Host trust as a security boundary that needs explicit justification.
@@ -0,0 +1,255 @@
1
+ ---
2
+ name: http-request-smuggling
3
+ description: HTTP request smuggling testing covering CL.TE, TE.CL, H2.CL, H2.TE, and HTTP/2 desync techniques with practical detection and exploitation methodology
4
+ ---
5
+
6
+ # HTTP Request Smuggling
7
+
8
+ HTTP request smuggling (HRS) exploits disagreements between a front-end proxy and a back-end server about where one HTTP request ends and the next begins. When the two systems parse `Content-Length` and `Transfer-Encoding` headers differently, an attacker can prefix a hidden request to the back-end's socket, which is then prepended to the next legitimate user's request. The impact ranges from bypassing front-end security controls to full cross-user session hijacking.
9
+
10
+ ## Attack Surface
11
+
12
+ **Infrastructure Topologies**
13
+ - CDN or load balancer in front of origin server (Cloudflare, Nginx, HAProxy, AWS ALB)
14
+ - Reverse proxy chains (Nginx → Gunicorn, HAProxy → Node.js, Varnish → Apache)
15
+ - API gateways forwarding to microservices
16
+ - HTTP/2 front-end to HTTP/1.1 back-end translation (H2.CL / H2.TE)
17
+ - Tunneling servers or WAFs that terminate and re-forward requests
18
+
19
+ **HTTP Versions in Play**
20
+ - HTTP/1.1: CL.TE and TE.CL classic smuggling
21
+ - HTTP/2: H2.CL (downgrade injects Content-Length) and H2.TE (injects Transfer-Encoding)
22
+ - HTTP/3: emerging QUIC-based desync (less common, research-stage)
23
+
24
+ **Parser Differentials**
25
+ - Treatment of duplicate `Content-Length` headers
26
+ - Handling of `Transfer-Encoding: chunked` when `Content-Length` is also present
27
+ - Chunk size obfuscation via whitespace, tab, case, or invalid extensions
28
+
29
+ ## High-Value Targets
30
+
31
+ - Front-end security controls (authentication bypass via desync)
32
+ - Endpoints shared by many users (high-traffic APIs, chat, feeds)
33
+ - Request capture endpoints (search, logging, analytics)
34
+ - Session-sensitive endpoints (auth callbacks, account settings)
35
+ - Internal admin interfaces proxied through the same connection pool
36
+
37
+ ## Core Concepts
38
+
39
+ ### CL.TE — Front-end uses Content-Length, Back-end uses Transfer-Encoding
40
+
41
+ Front-end reads `Content-Length: X` bytes and forwards. Back-end reads until the `0\r\n\r\n` chunk terminator. Attacker appends a hidden request after the `0` terminator that the front-end considers part of the same body but the back-end treats as a new request.
42
+
43
+ ```http
44
+ POST / HTTP/1.1
45
+ Host: target.com
46
+ Content-Length: 6
47
+ Transfer-Encoding: chunked
48
+
49
+ 0
50
+
51
+ G
52
+ ```
53
+ The `G` is left in the back-end's socket buffer and prepended to the next request.
54
+
55
+ ### TE.CL — Front-end uses Transfer-Encoding, Back-end uses Content-Length
56
+
57
+ Front-end reads chunked body to completion. Back-end reads only `Content-Length` bytes, leaving the remainder on the socket.
58
+
59
+ ```http
60
+ POST / HTTP/1.1
61
+ Host: target.com
62
+ Content-Type: application/x-www-form-urlencoded
63
+ Content-Length: 3
64
+ Transfer-Encoding: chunked
65
+
66
+ 8
67
+ SMUGGLED
68
+ 0
69
+
70
+
71
+ ```
72
+
73
+ ### H2.CL — HTTP/2 Front-end Downgrades to HTTP/1.1, Injects Content-Length
74
+
75
+ HTTP/2 has no `Content-Length` vs `TE` ambiguity in its own framing. But when the front-end downgrades to HTTP/1.1 for the back-end, an attacker can inject a `content-length` header in the HTTP/2 request that conflicts with the actual body length. Note: `content-length` is a regular HTTP/2 header — pseudo-headers are exclusively `:method`, `:path`, `:authority`, and `:scheme`:
76
+ ```
77
+ :method POST
78
+ :path /
79
+ :authority target.com
80
+ content-type application/x-www-form-urlencoded
81
+ content-length: 0
82
+
83
+ SMUGGLED_PREFIX
84
+ ```
85
+
86
+ ### H2.TE — HTTP/2 Injects Transfer-Encoding Header
87
+
88
+ Inject `transfer-encoding: chunked` in HTTP/2 headers (which the HTTP/2 spec forbids, but some front-ends pass through). Back-end receives both headers, may prefer TE over CL.
89
+
90
+ ```
91
+ :method POST
92
+ :path /
93
+ transfer-encoding: chunked
94
+
95
+ 0
96
+
97
+ SMUGGLED
98
+ ```
99
+
100
+ ## Key Vulnerabilities
101
+
102
+ ### Front-End Security Control Bypass
103
+
104
+ A front-end proxy enforces authentication or IP restriction by checking request headers and blocking or allowing based on rules. If a smuggled prefix bypasses the front-end (because it's buried in a prior request's body from the front-end's view), the back-end processes it without the security check.
105
+
106
+ **PoC structure (CL.TE):**
107
+ ```http
108
+ POST /not-restricted HTTP/1.1
109
+ Host: target.com
110
+ Content-Length: 100
111
+ Transfer-Encoding: chunked
112
+
113
+ 0
114
+
115
+ GET /admin HTTP/1.1
116
+ Host: target.com
117
+ X-Forwarded-Host: target.com
118
+ Content-Length: 10
119
+
120
+ x=1
121
+ ```
122
+ The `GET /admin` is seen by the back-end as a new, legitimate request originating from the trusted proxy IP.
123
+
124
+ ### Cross-User Request Capture
125
+
126
+ Poison the back-end socket with a partial request prefix that captures the next victim user's request (including their cookies, tokens, request body) into the response of a controlled endpoint (search, comment submission).
127
+
128
+ **PoC structure (CL.TE capture):**
129
+ ```http
130
+ POST /search HTTP/1.1
131
+ Host: target.com
132
+ Content-Length: 120
133
+ Transfer-Encoding: chunked
134
+
135
+ 0
136
+
137
+ POST /search HTTP/1.1
138
+ Host: target.com
139
+ Content-Type: application/x-www-form-urlencoded
140
+ Content-Length: 100
141
+
142
+ q=
143
+ ```
144
+ `Content-Length: 100` in the smuggled prefix is longer than the actual smuggled body, so the back-end waits for 100 bytes — which it sources from the *next* user's request. The `/search` endpoint reflects the query, capturing headers and body of the subsequent request.
145
+
146
+ ### Response Queue Poisoning
147
+
148
+ On pipelined connections, cause a misaligned response to be delivered to the wrong user (HTTP/1.1 response queue poisoning). Used to deliver attacker-controlled content or steal another user's response.
149
+
150
+ ### Request Reflection / Cache Poisoning Chain
151
+
152
+ Smuggle a prefix that hits a cacheable endpoint with an injected `Host` header. If the cache stores the response keyed only on URL, the poisoned response is served to all users requesting that URL.
153
+
154
+ ### WebSocket Handshake Hijacking
155
+
156
+ If the proxy performs WebSocket upgrade, a smuggled `Upgrade` request can hijack an existing WebSocket connection from a subsequent user.
157
+
158
+ ## Detection Techniques
159
+
160
+ ### Timing-Based Detection
161
+
162
+ **CL.TE:** Send a request where `Content-Length` is complete but `Transfer-Encoding` body is missing the `0\r\n\r\n` terminator. A CL.TE-vulnerable back-end waits for the terminator, causing a timeout.
163
+
164
+ ```http
165
+ POST / HTTP/1.1
166
+ Host: target.com
167
+ Transfer-Encoding: chunked
168
+ Content-Length: 6
169
+
170
+ 3
171
+ abc
172
+ X
173
+ ```
174
+ If response is delayed 10–30 seconds, CL.TE desync likely.
175
+
176
+ **TE.CL:** Send a request with a complete chunked body (including the `0\r\n\r\n` terminator so the front-end is satisfied) but with `Content-Length` set to **more** bytes than the body actually provides. The back-end, using Content-Length, waits for the remaining bytes that never arrive — producing a 10–30 second timeout. Setting Content-Length *less* than the body causes socket poisoning (differential-response detection), not a timeout.
177
+
178
+ ### Differential Response Detection
179
+
180
+ Send two requests in sequence. If the second request receives an unexpected response (error, redirect, wrong content), the first may have poisoned the socket. Use a unique string in the smuggled prefix to confirm.
181
+
182
+ ### Content-Length + Transfer-Encoding Combination
183
+
184
+ ```http
185
+ Transfer-Encoding: xchunked # non-standard value, some FE ignore, BE accept
186
+ Transfer-Encoding: chunked # leading space before value (0x20 byte after colon+space)
187
+ Transfer-Encoding: chunked # tab character before value
188
+ Transfer-Encoding: x
189
+ Transfer-Encoding: chunked # duplicate TE headers, BE uses last
190
+ ```
191
+
192
+ ## Transfer-Encoding Obfuscation
193
+
194
+ To force TE disagreement:
195
+ ```
196
+ Transfer-Encoding: xchunked
197
+ Transfer-Encoding : chunked # space before colon
198
+ X: X<CRLF>Transfer-Encoding: chunked # header injection — inject actual CRLF bytes at <CRLF>, not the literal string \r\n
199
+ Transfer-Encoding: chunked<CRLF>Transfer-Encoding: x # TE twice — inject actual CRLF bytes at <CRLF>
200
+ ```
201
+
202
+ ## HTTP/2-Specific Detection
203
+
204
+ - Send HTTP/2 requests with an injected `content-length` regular header that differs from the actual body length
205
+ - Inject `transfer-encoding: chunked` in HTTP/2 headers (spec-forbidden but sometimes passed through)
206
+ - Use HTTP/2 header injection: inject newlines in header values if the front-end passes them to HTTP/1.1 back-end unescaped
207
+ - Observe whether the HTTP/2 connection ID corresponds to a persistent HTTP/1.1 connection to the back-end (connection reuse amplifies impact)
208
+
209
+ ## Testing Methodology
210
+
211
+ 1. **Map the proxy chain** — identify front-end (CDN, load balancer, WAF) and back-end (app server)
212
+ 2. **Probe CL.TE** — send a timing probe with mismatched chunked terminator; observe delay
213
+ 3. **Probe TE.CL** — send a timing probe with complete chunked body but Content-Length larger than the actual body; observe back-end timeout
214
+ 4. **Obfuscate TE header** — try each obfuscation variant (tab, extra space, duplicate, non-standard value)
215
+ 5. **Confirm with differential response** — send two rapid identical requests; if second gets an unexpected response, socket is poisoned
216
+ 6. **Attempt bypass exploit** — craft a smuggled `GET /admin` or restricted endpoint and observe if back-end accepts it
217
+ 7. **Attempt capture** — poison with a partial POST pointing to a reflective endpoint; wait for a follow-up request to fill the buffer
218
+ 8. **Test H2.CL/H2.TE** — repeat the same probes over HTTP/2 connections if the target supports HTTP/2
219
+
220
+ ## Validation
221
+
222
+ 1. Show a timing differential of 10+ seconds on the CL.TE or TE.CL probe and explain the mechanism
223
+ 2. Demonstrate a bypass: smuggle a request to `/admin` and receive a 200 response where a direct request returns 403
224
+ 3. For capture: show a subsequent user's `Cookie` or `Authorization` header appearing in the response of a controlled endpoint
225
+ 4. Confirm with a unique marker string in the smuggled prefix to rule out timing noise
226
+ 5. Provide the exact raw bytes of the smuggled request
227
+
228
+ ## False Positives
229
+
230
+ - General network latency or server-side processing delays unrelated to smuggling
231
+ - Server consistently close connection after first request (no connection reuse, no socket sharing)
232
+ - HTTP/2 with full end-to-end HTTP/2 to back-end (no HTTP/1.1 downgrade, no desync surface)
233
+ - WAF or proxy that normalizes TE/CL headers before forwarding (removes the ambiguity)
234
+
235
+ ## Impact
236
+
237
+ - Authentication and authorization bypass by smuggling requests past front-end access controls
238
+ - Cross-user session hijacking by capturing requests containing session tokens
239
+ - Cache poisoning affecting all users of a cached resource
240
+ - Internal service access bypassing IP-based restrictions enforced at the front-end
241
+ - XSS delivery via response queue poisoning in shared connection contexts
242
+
243
+ ## Pro Tips
244
+
245
+ 1. Use Burp Suite's HTTP Request Smuggler extension as a rapid scanner, but always confirm manually — false positives are common
246
+ 2. TE obfuscation is the most reliable path; `Transfer-Encoding: xchunked` works on many Apache/IIS back-ends
247
+ 3. Keep smuggled prefixes short during detection; use the minimal body to confirm desync before attempting capture attacks
248
+ 4. H2.CL is the most impactful modern variant — many CDNs translate HTTP/2 to HTTP/1.1 and derive `Content-Length` from the `content-length` regular header sent in the HTTP/2 request (not a pseudo-header — inject it as a normal header field)
249
+ 5. In capture attacks, set `Content-Length` in the smuggled prefix larger than your partial body by 50–100 bytes to catch a full auth header from the next user
250
+ 6. Test during low-traffic periods first to avoid affecting real users; always get explicit authorization for capture attempts
251
+ 7. If timing probes are inconsistent, pipeline two requests over the same connection and look for unexpected response swapping
252
+
253
+ ## Summary
254
+
255
+ HTTP request smuggling is eliminated by enforcing consistent TE/CL interpretation at every hop in the proxy chain, preferring end-to-end HTTP/2, and having back-end servers reject or normalize ambiguous requests. At the proxy level, never forward TE headers that were not present in the original request, and treat conflicting CL + TE as a hard error.