[Bug]: host-rewrite policy accepts Host values its docs forbid, including CRLF, spaces, null bytes and lengths over 255
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 72/100
Research direction
The affected policy is in policies/host-rewrite/hostrewrite.go; the report also points to policies/redirect/redirect.go and its hostnamePattern for comparison. Read parseConfig and the Host validation documented in docs/host-rewrite/.../host-rewrite.md, then run the reproducer described in the issue. Done means values outside the documented character and length limits are rejected while ok.example.com is accepted.
Written by the indexing model from the issue text.
Description
Please select the area the issue is related to
Gateway
Please select the aspect the issue is related to
Aspect/API (API backends, definitions, contracts, interfaces, OpenAPI)
Description
The host-rewrite policy (wso2/gateway-controllers, policies/host-rewrite/hostrewrite.go, policy version v1.0.1) is documented as accepting only a Host made of letters, digits, - and ., with length 1 to 255 (docs/host-rewrite/.../host-rewrite.md, Configuration table). Its parseConfig function only checks that the string is non-empty after TrimSpace:
host = strings.TrimSpace(host)
if host == "" {
return nil, fmt.Errorf("host parameter cannot be empty")
}
Anything else is returned as UpstreamRequestHeaderModifications{Host: &cfg.Host} and becomes the upstream :authority / Host. Measured cases that the docs say must be refused, but that the policy accepts:
host value |
Documented | Actual |
|---|---|---|
ok.example.com |
accept | accept |
a b (space) |
reject | accept |
evil.com\r\nX-Injected: yes (CRLF) |
reject | accept |
host_with_underscore |
reject | accept |
127.0.0.1:8080 (colon / port) |
reject | accept |
| 300 null bytes | reject (length) | accept |
A Host that contains CRLF is especially harmful: if the gateway forwards it as a header value, it is a classic header-injection shape. Even when Envoy later refuses the value, the policy has already accepted a configuration its own docs call invalid, and the redirect policy in the same repository already validates hostname characters with a regex (policies/redirect/redirect.go, hostnamePattern).
Note: filed in wso2/api-platform because wso2/gateway-controllers, where the policy lives, has issues disabled.
Steps to Reproduce
On wso2/gateway-controllers main c5d83e0, add this test to policies/host-rewrite and run go test -run TestZZDocMismatch -v ..
func TestZZDocMismatch(t *testing.T) {
for _, h := range []string{
"ok.example.com",
"a b",
"evil.com\r\nX-Injected: yes",
"host_with_underscore",
"127.0.0.1:8080",
string(make([]byte, 300)),
} {
a := ins.OnRequestHeaders(context.Background(), &policy.RequestHeaderContext{
SharedContext: &policy.SharedContext{}, Headers: policy.NewHeaders(nil),
}, map[string]interface{}{"host": h})
switch v := a.(type) {
case policy.ImmediateResponse:
fmt.Printf("REJECT %q -> %d\n", h[:min(40, len(h))], v.StatusCode)
case policy.UpstreamRequestHeaderModifications:
fmt.Printf("ACCEPT %q -> %q\n", h[:min(40, len(h))], (*v.Host)[:min(40, len(*v.Host))])
}
}
}
Expected behavior
Only ok.example.com is accepted. Every other value returns a 500 configuration error, matching the docs.
Actual behavior
ACCEPT "ok.example.com" -> "ok.example.com"
ACCEPT "a b" -> "a b"
ACCEPT "evil.com\r\nX-Injected: yes" -> "evil.com\r\nX-Injected: yes"
ACCEPT "host_with_underscore" -> "host_with_underscore"
ACCEPT "127.0.0.1:8080" -> "127.0.0.1:8080"
ACCEPT "<300 null bytes>" -> "<300 null bytes>"
Severity Level of the Issue
Severity/Minor (Non-critical functionality. Can be fixed in future releases)
Environment Details (with versions)
- wso2/gateway-controllers main
c5d83e0(host-rewrite policy v1.0.1, sdk/core v0.3.4) - Go 1.27.2, Debian Linux x86_64
- Dominant language
- Go
- Stars
- 76
- Forks
- 126
- Avg merge
- 2d 8h
- Merged PRs (30d)
- 181
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- No contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from wso2/api-platform
-
Aspect/API Severity/Major Type/Bug
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
wso2/api-platform#3899 ·
Maintainers usually reply within 1 day
-
Aspect/API Severity/Minor Type/Bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
wso2/api-platform#3885 · 1 comment ·
Maintainers usually reply within 1 day
-
Aspect/API Severity/Minor Type/Bug
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
wso2/api-platform#3882 · 1 comment ·
Maintainers usually reply within 1 day
-
[Bug]: Deleting an MCP proxy leaves its API keys in the gateway's memory and in the policy engineOpenAspect/API Aspect/Other Severity/Minor Type/Bug
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
wso2/api-platform#3852 ·
Maintainers usually reply within 1 day
-
[Bug]: Policy-engine sampler ignores the parent's sampling decision, producing orphan spans and partial tracesPossibly taken @lahiruudayakumara claimed this 10 days ago. OpenArea/Gateway Aspect/Monitoring Severity/Major Type/Bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
wso2/api-platform#3735 ·
Maintainers usually reply within 1 day
All issues in wso2/api-platform
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
FiloSottile/age#758 ·
-
nginx configOpen
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 63/100
Maintainers usually reply within 1 day