go-chi / go-chi/chi

Compress middleware: matchAcceptEncoding uses substring match and ignores q=0

Open
#1,069 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
22.8k
Forks
1.2k
Avg merge
5h 17m
Merged PRs (30d)
10

Description

## Description

The `matchAcceptEncoding` function in `middleware/compress.go` uses `strings.Contains` to match encoding names in the `Accept-Encoding` header. This has two problems:

### 1. Substring matching produces false positives

```go
func matchAcceptEncoding(accepted []string, encoding string) bool {
for _, v := range accepted {
if strings.Contains(v, encoding) { // substring match, not exact
return true
}
}
return false
}
```

For example:
- `Accept-Encoding: br` incorrectly matches encoding `b` (since `"br"` contains `"b"`)
- `Accept-Encoding: bgzip` incorrectly matches encoding `gzip`

### 2. Quality value `q=0` is ignored

Per [RFC 9110 Section 12.5.3](https://httpwg.org/specs/rfc9110.html#field.accept-encoding), a quality value of `q=0` means the encoding is **not acceptable**. But `strings.Contains("gzip;q=0", "gzip")` returns `true`, so the middleware will compress with gzip even when the client explicitly rejects it.

## Reproduction

```go
// These all incorrectly return true:
matchAcceptEncoding([]string{"gzip;q=0"}, "gzip") // should be false (q=0 = not acceptable)
matchAcceptEncoding([]string{"br"}, "b") // should be false (not exact match)
matchAcceptEncoding([]string{"bgzip"}, "gzip") // should be false (not exact match)
```

## Fix

Parse the encoding name properly by splitting on `;` to separate quality parameters, trimming whitespace, performing exact string comparison, and rejecting `q=0`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.