fix(middleware/static): don't double-unescape request path (#2599)#3006
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem (#2599)
A file whose name contains a percent sign cannot be downloaded via the static middleware:
100%.txt→GET /100%25.txt→invalid URL escape "%.t"(500)foo%20bar.txt→GET /foo%2520bar.txt→ serves the wrong/missing filehttp.Request.URL.Pathis already decoded by net/http (per its docs), but the middleware unescaped it a second time.Fix
Default
pathUnescapetofalse. The non-group path comes fromURL.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 existingDisablePathUnescapingtoggle — so group behavior is unchanged.Test
TestStatic_servesFileWithPercentInName(written first; fails on master with 500) using an in-memoryfstest.MapFS. gofmt/vet clean; allTestStatic*and the full middleware package pass (group/DisablePathUnescapingcases unaffected).Fixes #2599.
🤖 Generated with Claude Code