Describe the bug
The HTTP Metrics middleware (pkg/gofr/http/middleware/metrics.go) records r.URL.Path verbatim as the value of the Prometheus path label on the app_http_response histogram,
with no UTF-8 validation. Any request whose URL path contains non-UTF-8 bytes (vulnerability scanners like Nessus routinely send IIS Unicode path-traversal probes such as
\xc0.\xc0./winnt/win.ini) poisons the OTel registry. Subsequent scrapes of /metrics then fail with:
An error has occurred while serving metrics:
error collecting metric Desc{fqName: "app_http_response", help: "Response time of HTTP requests in seconds.", constLabels: {}, variableLabels: {method,path,status,otel_scope_name,otel_scope_version,otel_scope_schema_url}}: label value "/\xc0.\xc0./winnt/win.ini" is not valid UTF-8
Per the Prometheus exposition format spec, label values must be valid UTF-8, so this is a violation of contract — not just a cosmetic issue. Once a single bad series enters the
registry, the whole scrape can be reported as failing.
To Reproduce
- The code is
Minimal app:
app := gofr.New()
app.GET("/healthz", func(*gofr.Context) (any, error) { return "ok", nil })
app.Run()
Send a non-UTF-8 path and scrape:
curl -i "http://localhost:8000/$(printf '\xc0\x2e\xc0\x2e')/winnt/win.ini"
# → 404 (expected — no such route)
curl -s http://localhost:2121/metrics
# → "An error has occurred while serving metrics: ... label value ...
# is not valid UTF-8"
- The error is
error collecting metric Desc{fqName: "app_http_response", help: "Response time of HTTP requests in seconds.", constLabels: {}, variableLabels: {method,path,status,otel_scope_name,otel_scope_version,otel_scope_schema_url}}: label value "/\xc0.\xc0./winnt/win.ini" is not valid UTF-8
Expected behavior
app_http_response's path label should always be valid UTF-8
(Prometheus contract) and should have bounded cardinality (best
practice, no DoS surface from a scanner).
Environments (please complete the following information):
- gofr: reproduced on
v1.56.X
- Go: 1.26
- Any OS exposing the gofr HTTP port to a network reachable by an HTTP
scanner (Linux production setups especially)
Proposed fix
A single validation after all assignment branches.
import "unicode/utf8"
// ... after L39 ("if path == "/" || ...") ...
if !utf8.ValidString(path) {
path = "/<invalid_utf8>"
}
path = strings.TrimSuffix(path, "/") // existing L41
Describe the bug
The HTTP
Metricsmiddleware (pkg/gofr/http/middleware/metrics.go) recordsr.URL.Pathverbatim as the value of the Prometheuspathlabel on theapp_http_responsehistogram,with no UTF-8 validation. Any request whose URL path contains non-UTF-8 bytes (vulnerability scanners like Nessus routinely send IIS Unicode path-traversal probes such as
\xc0.\xc0./winnt/win.ini) poisons the OTel registry. Subsequent scrapes of/metricsthen fail with:An error has occurred while serving metrics:
error collecting metric Desc{fqName: "app_http_response", help: "Response time of HTTP requests in seconds.", constLabels: {}, variableLabels: {method,path,status,otel_scope_name,otel_scope_version,otel_scope_schema_url}}: label value "/\xc0.\xc0./winnt/win.ini" is not valid UTF-8
Per the Prometheus exposition format spec, label values must be valid UTF-8, so this is a violation of contract — not just a cosmetic issue. Once a single bad series enters the
registry, the whole scrape can be reported as failing.
To Reproduce
Minimal app:
Send a non-UTF-8 path and scrape:
Expected behavior
app_http_response'spathlabel should always be valid UTF-8(Prometheus contract) and should have bounded cardinality (best
practice, no DoS surface from a scanner).
Environments (please complete the following information):
v1.56.Xscanner (Linux production setups especially)
Proposed fix
A single validation after all assignment branches.