-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Description
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:
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:
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