Stricter path sanitization

Goji routes incoming requests without first URL decoding the path, so
'%2F' in a URL will not be decoded to a '/' before routing. But by the
time that we perform the path checks for private urls on r.URL.Path,
these characters have been decoded.

As a consequence, a user 'foo' could use 'foo%2Fbar' as the repo name.
The private repo check would see that the path starts with 'foo/' and
allow it, and rest-server would happily create a 'foo/bar' repo. Other
more harmful variants are possible.

To resolve this issue, we now reject any name part that contains a '/'.

Additionally, we immediately reject a few other characters that are
disallowed under some operating systems or filesystems.
This commit is contained in:
Konrad Wojas 2020-05-01 22:11:37 +08:00 committed by Alexander Neumann
parent 6367043b2c
commit f8e774393c

View file

@ -44,11 +44,18 @@ func (s *Server) isHashed(dir string) bool {
}
func valid(name string) bool {
// taken from net/http.Dir
// Based on net/http.Dir
if strings.Contains(name, "\x00") {
return false
}
// Path characters that are disallowed or unsafe under some operating systems
// are not allowed here.
// The most important one here is '/', since Goji does not decode '%2F' to '/'
// during routing, so we can end up with a '/' in the name here.
if strings.ContainsAny(name, "/\\:*?\"<>|") {
return false
}
if filepath.Separator != '/' && strings.ContainsRune(name, filepath.Separator) {
return false
}