mirror of
https://github.com/golang/go.git
synced 2025-10-19 11:03:18 +00:00
net/http: make http.FileServer return 404 when a path is invalid/unsafe
This PR adds error handling in net/http toHTTPError to return a 404
instead of a 500 when net/http fs.Dir.Open throws the error http:
invalid or unsafe file path.
Fixes #72091
Change-Id: I7941c8fca5160a4a82732dc1d05b9b95eac84fbf
GitHub-Last-Rev: 04b5019dfb
GitHub-Pull-Request: golang/go#72108
Reviewed-on: https://go-review.googlesource.com/c/go/+/654975
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
This commit is contained in:
parent
37026a7c56
commit
061efaa8a7
2 changed files with 30 additions and 1 deletions
|
@ -67,6 +67,11 @@ func mapOpenError(originalErr error, name string, sep rune, stat func(string) (f
|
|||
return originalErr
|
||||
}
|
||||
|
||||
// errInvalidUnsafePath is returned by Dir.Open when the call to
|
||||
// filepath.Localize fails. filepath.Localize returns an error if the path
|
||||
// cannot be represented by the operating system.
|
||||
var errInvalidUnsafePath = errors.New("http: invalid or unsafe file path")
|
||||
|
||||
// Open implements [FileSystem] using [os.Open], opening files for reading rooted
|
||||
// and relative to the directory d.
|
||||
func (d Dir) Open(name string) (File, error) {
|
||||
|
@ -76,7 +81,7 @@ func (d Dir) Open(name string) (File, error) {
|
|||
}
|
||||
path, err := filepath.Localize(path)
|
||||
if err != nil {
|
||||
return nil, errors.New("http: invalid or unsafe file path")
|
||||
return nil, errInvalidUnsafePath
|
||||
}
|
||||
dir := string(d)
|
||||
if dir == "" {
|
||||
|
@ -768,6 +773,9 @@ func toHTTPError(err error) (msg string, httpStatus int) {
|
|||
if errors.Is(err, fs.ErrPermission) {
|
||||
return "403 Forbidden", StatusForbidden
|
||||
}
|
||||
if errors.Is(err, errInvalidUnsafePath) {
|
||||
return "404 page not found", StatusNotFound
|
||||
}
|
||||
// Default:
|
||||
return "500 Internal Server Error", StatusInternalServerError
|
||||
}
|
||||
|
|
|
@ -733,6 +733,27 @@ func testFileServerZeroByte(t *testing.T, mode testMode) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestFileServerNullByte(t *testing.T) { run(t, testFileServerNullByte) }
|
||||
func testFileServerNullByte(t *testing.T, mode testMode) {
|
||||
ts := newClientServerTest(t, mode, FileServer(Dir("testdata"))).ts
|
||||
|
||||
for _, path := range []string{
|
||||
"/file%00",
|
||||
"/%00",
|
||||
"/file/qwe/%00",
|
||||
} {
|
||||
res, err := ts.Client().Get(ts.URL + path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
res.Body.Close()
|
||||
if res.StatusCode != 404 {
|
||||
t.Errorf("Get(%q): got status %v, want 404", path, res.StatusCode)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileServerNamesEscape(t *testing.T) { run(t, testFileServerNamesEscape) }
|
||||
func testFileServerNamesEscape(t *testing.T, mode testMode) {
|
||||
ts := newClientServerTest(t, mode, FileServer(Dir("testdata"))).ts
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue