Merge "scouting: Make /sha256/ requests stricter"
diff --git a/scouting/webserver/static/static.go b/scouting/webserver/static/static.go
index 4c46fe7..fbad476 100644
--- a/scouting/webserver/static/static.go
+++ b/scouting/webserver/static/static.go
@@ -81,7 +81,14 @@
log.Println(err)
return nil
}
- shaSums[hash] = "/" + strings.TrimPrefix(path, directory)
+ // We want all paths relative to the original search directory.
+ // That means we remove the search directory from the Walk()
+ // result. Also make sure that the final path doesn't start
+ // with a "/" to make it independent of whether "directory"
+ // ends with a "/" or not.
+ trimmedPath := strings.TrimPrefix(path, directory)
+ trimmedPath = strings.TrimPrefix(trimmedPath, "/")
+ shaSums[hash] = trimmedPath
return nil
})
if err != nil {
@@ -101,9 +108,9 @@
// [0] ""
// [1] "sha256"
// [2] "<checksum>"
- // [3-] path...
- parts := strings.Split(r.URL.Path, "/")
- if len(parts) < 4 {
+ // [3] path...
+ parts := strings.SplitN(r.URL.Path, "/", 4)
+ if len(parts) != 4 {
w.WriteHeader(http.StatusNotFound)
return
}
@@ -114,6 +121,14 @@
}
hash := parts[2]
if path, ok := shaSums[hash]; ok {
+ // The path must match what it would be without the
+ // /sha256/<checksum>/ prefix. Otherwise it's too easy
+ // to make copy-paste mistakes.
+ if path != parts[3] {
+ log.Println("Got ", parts[3], "expected", path)
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
// We found a file with this checksum. Serve that file.
r.URL.Path = path
} else {
diff --git a/scouting/webserver/static/static_test.go b/scouting/webserver/static/static_test.go
index 09ed940..1d036a0 100644
--- a/scouting/webserver/static/static_test.go
+++ b/scouting/webserver/static/static_test.go
@@ -92,6 +92,14 @@
t.Fatal("Failed to get data ", err)
}
expectEqual(t, resp.Status, "404 Not Found")
+
+ // Make a request with a valid checksum but invalid path and make sure
+ // we get a 400.
+ resp, err = http.Get("http://localhost:8080/sha256/553b9b29647a112136986cf93c57b988d1f12dc43d3b774f14a24e58d272dbff/not_root.txt")
+ if err != nil {
+ t.Fatal("Failed to get data ", err)
+ }
+ expectEqual(t, resp.Status, "400 Bad Request")
}
// Retrieves the data at the specified path. If an error occurs, the test case