scouting: Make /sha256/ requests stricter
Before this patch, requesting a file via its checksum only required
the checksum itself. The path specified after the checksum was
ignored. This meant that it was actually pretty easy to screw up the
checksum with copy-paste errors.
Signed-off-by: Philipp Schrader <philipp.schrader@gmail.com>
Change-Id: I382ae36f3be3eb373e261186cf399b6316e5f21d
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