Hacktricks-skills h2c-websocket-smuggling
How to perform H2C (HTTP/2 over cleartext) and WebSocket smuggling attacks to bypass reverse proxy protections. Use this skill whenever you need to test for upgrade header smuggling vulnerabilities, bypass WAF/proxy rules, access internal endpoints behind a reverse proxy, or when you encounter HAProxy, Traefik, NGINX, Apache, AWS ALB/CLB, or other proxies that might forward Upgrade headers. Trigger this skill for any pentesting task involving HTTP upgrade mechanisms, WebSocket connections, or when standard requests are blocked but you suspect a proxy misconfiguration.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/pentesting-web/h2c-smuggling/SKILL.MDH2C and WebSocket Smuggling
This skill covers two related techniques for bypassing reverse proxy protections by exploiting how proxies handle connection upgrade headers.
When to Use This Skill
Use this skill when:
- You need to bypass WAF rules or proxy-based access controls
- You've identified a reverse proxy in the attack path
- Standard HTTP requests are blocked but you suspect internal endpoints exist
- You're testing for HTTP/2 upgrade vulnerabilities
- You encounter WebSocket endpoints that might be misconfigured
- You need to access internal APIs behind a proxy
H2C (HTTP/2 Over Cleartext) Smuggling
What It Is
H2C smuggling exploits how reverse proxies handle HTTP/2 upgrade requests. When a proxy receives an
Upgrade: h2c request, it establishes a persistent connection and stops processing individual requests. This allows you to bypass proxy rules like path-based routing, authentication, and WAF processing.
Required Headers
A compliant H2C upgrade requires these three headers:
Upgrade: h2c HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA Connection: Upgrade, HTTP2-Settings
Vulnerable Proxies
Inherently vulnerable (forward headers by default):
- HAProxy
- Traefik
- Nuster
Potentially vulnerable (if misconfigured to forward headers):
- AWS ALB/CLB
- NGINX
- Apache
- Squid
- Varnish
- Kong
- Envoy
- Apache Traffic Server
Exploitation Steps
- Identify the proxy - Determine what reverse proxy is in front of the target
- Test for H2C support - Send an upgrade request with the required headers
- Establish the connection - If successful, the proxy maintains a persistent connection
- Send HTTP/2 requests - Use the established connection to send requests directly to the backend
- Bypass protections - Access internal endpoints that the proxy would normally block
Tools
- h2csmuggler (BishopFox): https://github.com/BishopFox/h2csmuggler
- h2csmuggler (Assetnote): https://github.com/assetnote/h2csmuggler
Important Note
Regardless of the path specified in the proxy's
proxy_pass URL (e.g., http://backend:9999/socket.io), the established connection defaults to http://backend:9999. This means you can access any path on the internal endpoint, not just the configured path.
WebSocket Smuggling
What It Is
WebSocket smuggling establishes a WebSocket tunnel to bypass proxy limitations. Unlike H2C smuggling which creates an HTTP/2 tunnel, this technique exploits how proxies validate WebSocket upgrade requests.
Scenario 1: Invalid Protocol Version
Setup: Backend has a public WebSocket API and an inaccessible internal REST API.
Attack Flow:
- Send an Upgrade request with an incorrect
headerSec-WebSocket-Version - The proxy forwards it to the backend without validating the version
- Backend responds with
(Upgrade Required) due to invalid version426 - Proxy ignores the 426 status and assumes WebSocket connection is established
- Proxy maintains open TCP/TLS connection between client and backend
- Client can now access the internal REST API through this connection
Affected Proxies:
- Varnish (declined to fix)
- Envoy proxy version 1.8.0 or older
- Other proxies may be susceptible
Scenario 2: Health Check Exploitation
Setup: Backend has public WebSocket API, public health check REST API, and inaccessible internal REST API.
Attack Flow:
- Send a POST request to the health check API with
headerUpgrade: websocket - NGINX interprets this as a standard Upgrade request based on the header alone
- Backend executes health check, which calls an external attacker-controlled resource
- Attacker's resource returns HTTP 101 (Switching Protocols)
- Backend forwards this 101 response to NGINX
- NGINX validates only the status code and assumes WebSocket connection is established
- Proxy maintains the connection, allowing access to internal REST API
Requirements:
- External SSRF vulnerability (to make the backend call attacker-controlled resource)
- Ability to return HTTP 101 status code
Affected Proxies: Most reverse proxies are vulnerable, but exploitation requires SSRF capability.
Testing Both Scenarios
Labs available at: https://github.com/0ang3el/websocket-smuggle.git
Practical Testing Workflow
Step 1: Reconnaissance
- Identify the reverse proxy in use (check response headers, behavior)
- Map public endpoints (WebSocket APIs, REST APIs, health checks)
- Look for internal endpoints that might be accessible
- Check for SSRF vulnerabilities (needed for Scenario 2)
Step 2: H2C Testing
# Using h2csmuggler curl -i -H "Upgrade: h2c" \ -H "HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA" \ -H "Connection: Upgrade, HTTP2-Settings" \ http://target:8080
If the connection upgrades successfully, you can send HTTP/2 requests through it.
Step 3: WebSocket Testing
Scenario 1:
curl -i -H "Upgrade: websocket" \ -H "Connection: Upgrade" \ -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \ -H "Sec-WebSocket-Version: 999" \ http://target:8080/websocket
Scenario 2:
# Requires SSRF to external endpoint returning 101 curl -X POST -H "Upgrade: websocket" \ http://target:8080/health-check
Step 4: Exploitation
Once the connection is established:
- Send requests directly to internal endpoints
- Bypass authentication checks
- Access restricted resources
- Enumerate internal services
Safety and Ethics
- Only test systems you have explicit authorization to test
- These techniques can be disruptive to production systems
- Document findings responsibly
- Consider the impact on service availability