Skip to content

net/http: ServeFile and FileServer information leak #46413

@empijei

Description

@empijei

ServeFile and FileServer are used to serve static files.

These files have to exists on the server or the two functions will return a 404.

The issue is that both function don't just return 404 by default, but they try to return an error that gives information on the server's local filesystem:

go/src/net/http/fs.go

Lines 597 to 610 in 3075ffc

f, err := fs.Open(name)
if err != nil {
msg, code := toHTTPError(err)
Error(w, msg, code)
return
}
defer f.Close()
d, err := f.Stat()
if err != nil {
msg, code := toHTTPError(err)
Error(w, msg, code)
return
}

This is the current implementation of toHTTPError:

go/src/net/http/fs.go

Lines 672 to 681 in 3075ffc

func toHTTPError(err error) (msg string, httpStatus int) {
if errors.Is(err, fs.ErrNotExist) {
return "404 page not found", StatusNotFound
}
if errors.Is(err, fs.ErrPermission) {
return "403 Forbidden", StatusForbidden
}
// Default:
return "500 Internal Server Error", StatusInternalServerError
}

This means that an attacker can probe the server's filesystem and discover potentially existing files that the server can't access, or otherwise infer information on the current directory tree (even if those paths are not accessible by the user running the server).

I propose we change this behavior to make all errors returned by serveFile be a 404.

Note that there already are security-sensitive implementations out there trying to get around this kind of behavior. It would be nice if people didn't have to wrap the response writer in order to avoid introducing OWASP TESTING GUIDE-4.8.1: Improper error handling in their code.

/cc @FiloSottile @katiehockman @rolandshoemaker @bradfitz @neild

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions