Skip to content

fix(middleware/static): don't double-unescape request path (#2599)#3006

Merged
vishr merged 2 commits into
masterfrom
fix-2599-static-double-unescape
Jun 13, 2026
Merged

fix(middleware/static): don't double-unescape request path (#2599)#3006
vishr merged 2 commits into
masterfrom
fix-2599-static-double-unescape

Conversation

@vishr

@vishr vishr commented Jun 13, 2026

Copy link
Copy Markdown
Member

Problem (#2599)

A file whose name contains a percent sign cannot be downloaded via the static middleware:

  • 100%.txtGET /100%25.txtinvalid URL escape "%.t" (500)
  • foo%20bar.txtGET /foo%2520bar.txt → serves the wrong/missing file

http.Request.URL.Path is already decoded by net/http (per its docs), but the middleware unescaped it a second time.

Fix

Default pathUnescape to false. The non-group path comes from URL.Path (already decoded), so it must not be unescaped again. Only the wildcard param from a group route (c.Param("*"), set explicitly) may still be escaped, and that case keeps its existing DisablePathUnescaping toggle — so group behavior is unchanged.

GET /100%25.txt       → 200  "hundred percent"
GET /foo%2520bar.txt  → 200  "literal percent twenty"

Test

TestStatic_servesFileWithPercentInName (written first; fails on master with 500) using an in-memory fstest.MapFS. gofmt/vet clean; all TestStatic* and the full middleware package pass (group/DisablePathUnescaping cases unaffected).

Fixes #2599.

🤖 Generated with Claude Code

vishr and others added 2 commits June 13, 2026 13:13
http.Request.URL.Path is already decoded by net/http, but the static
middleware unescaped it again by default, so files whose names contain a
percent sign were not downloadable ("/100%25.txt" -> "invalid URL escape").

Default pathUnescape to false; only the wildcard param from a group route
(set explicitly below) may still be escaped and is handled by the existing
DisablePathUnescaping toggle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Companion test confirming that defaulting pathUnescape to false does not
weaken traversal protection — single-, double-, and dot-encoded "../" all
stay within the served root.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vishr vishr merged commit a9ede66 into master Jun 13, 2026
8 checks passed
@vishr vishr deleted the fix-2599-static-double-unescape branch June 13, 2026 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

static middleware: path ist unescaped twice for file names, leading to not downloadable content

1 participant