# 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.

- Skill: `abelrguezr/h2c-websocket-smuggling` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/h2c-websocket-smuggling`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/h2c-websocket-smuggling/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/h2c-websocket-smuggling

---


# H2C 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

1. **Identify the proxy** - Determine what reverse proxy is in front of the target
2. **Test for H2C support** - Send an upgrade request with the required headers
3. **Establish the connection** - If successful, the proxy maintains a persistent connection
4. **Send HTTP/2 requests** - Use the established connection to send requests directly to the backend
5. **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**:
1. Send an Upgrade request with an incorrect `Sec-WebSocket-Version` header
2. The proxy forwards it to the backend without validating the version
3. Backend responds with `426` (Upgrade Required) due to invalid version
4. Proxy ignores the 426 status and assumes WebSocket connection is established
5. Proxy maintains open TCP/TLS connection between client and backend
6. 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**:
1. Send a POST request to the health check API with `Upgrade: websocket` header
2. NGINX interprets this as a standard Upgrade request based on the header alone
3. Backend executes health check, which calls an external attacker-controlled resource
4. Attacker's resource returns HTTP 101 (Switching Protocols)
5. Backend forwards this 101 response to NGINX
6. NGINX validates only the status code and assumes WebSocket connection is established
7. 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

1. Identify the reverse proxy in use (check response headers, behavior)
2. Map public endpoints (WebSocket APIs, REST APIs, health checks)
3. Look for internal endpoints that might be accessible
4. Check for SSRF vulnerabilities (needed for Scenario 2)

### Step 2: H2C Testing

```bash
# 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**:
```bash
curl -i -H "Upgrade: websocket" \
     -H "Connection: Upgrade" \
     -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
     -H "Sec-WebSocket-Version: 999" \
     http://target:8080/websocket
```

**Scenario 2**:
```bash
# 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:
1. Send requests directly to internal endpoints
2. Bypass authentication checks
3. Access restricted resources
4. 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

## References

- [Assetnote H2C Smuggling Blog](https://blog.assetnote.io/2021/03/18/h2c-smuggling/)
- [BishopFox H2C Smuggling Blog](https://bishopfox.com/blog/h2c-smuggling-request)
- [WebSocket Smuggle Labs](https://github.com/0ang3el/websocket-smuggle.git)
- [NGINX Proxy Header Configuration](../network-services-pentesting/pentesting-web/nginx.md#proxy_set_header-upgrade-and-connection)

