# CrowdSec AppSec silently drops request body for chunked / HTTP-2 requests

CrowdSec AppSec reads zero bytes when ContentLength is -1, so chunked or HTTP/2 requests bypass all body-based WAF rules silently.

- Payout: Research
- Severity: high
- Program: CrowdSec
- Found by: mmarting
- Disclosed: 2026-05-27
- CVE: CVE-2026-44982
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-rw47-hm26-6wr7
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-rw47-hm26-6wr7
- Tags: area:web domain:web impact:integrity kind:research platform:ghsa sev:high tech:go technique:parser-differential technique:source-review vuln:access-control vuln:misconfiguration

**Target:** AppSec WAF request parser (pkg/appsec/request.go NewParsedRequestFromRequest)
**Root cause:** max(r.ContentLength, 0) turns Go's -1 sentinel (chunked / HTTP/2 without content-length) into a zero-length buffer; io.ReadFull on an empty slice returns immediately without reading r.Body, so the body is replaced with empty bytes.
**Steps:**
1. Send a request with `Transfer-Encoding: chunked` (no Content-Length) or an HTTP/2 request omitting `content-length`, carrying a malicious body.
2. Go net/http sets r.ContentLength = -1.
3. NewParsedRequestFromRequest computes max(-1,0)=0, allocates make([]byte,0), io.ReadFull reads nothing, empty buffer written back to r.Body and cloned request.
4. Coraza evaluates empty body; body-zone rules (REQUEST_BODY, BODY_ARGS, ARGS_POST, JSON, XML) never match; request forwarded as allow with no WAF log.
**How found:** Code review of the body-reading path: noticing ContentLength is used directly to size the buffer and that Go uses -1 as a sentinel for unknown length, then tracing that max(-1,0) yields a zero-length read.
**Exploitation:** Attacker takes any payload that would trigger a body-inspection rule and adds `Transfer-Encoding: chunked` (or drops content-length on HTTP/2); the WAF sees an empty body and forwards the request unblocked and unlogged.
**Insight:** When auditing WAF/proxy body handling, check how the framework's unknown-length sentinel (Go's ContentLength=-1, chunked, HTTP/2 DATA-only) interacts with buffer sizing; a clamp-to-zero silently disables inspection rather than erroring.

