Treat git's own path-traversal rejection as not-found, not a 500
?path=../../../etc/passwd on a repo blob returned a raw 500 — git already refuses it ("relative path syntax can't be used outside working tree"), so nothing was ever exposed, but that specific error message wasn't in notFoundGitError's list, so it surfaced as a server error instead of the usual clean 404. Found while re-checking the older file-browsing code for the argument-injection bug class fixed in 0.10.1 — this one isn't that (no injection, git blocks it itself), just inconsistent error handling.
2 files changed
+6 −1
M
CHANGELOG.md
+4 −0
M
internal/gitexec/gitexec.go
+2 −1
CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## 0.10.3
+
+- A file path outside the repo tree (e.g. `?path=../../../etc/passwd`) returned a raw 500 instead of the usual 404 — git itself already rejects it (`relative path syntax can't be used outside working tree`), so nothing was ever exposed, but gitfed didn't recognize that error as "not found" like it does every other one. Found while re-checking the older file-browsing code for the same bug class as 0.10.1's fix.
+
## 0.10.2
- Merge request title/description/comment length limits are now enforced server-side, not just as HTML `maxlength` attributes a direct POST trivially bypasses. Found during the same audit as 0.10.1's fix; full writeup in `docs/security/AUDIT-2026-07-29b.md`.
internal/gitexec/gitexec.go
@@ -197,7 +197,8 @@ func notFoundGitError(msg string) bool {
strings.Contains(msg, "not in the tree") ||
strings.Contains(msg, "invalid object name") ||
strings.Contains(msg, "valid object name") ||
- strings.Contains(msg, "not a tree object")
+ strings.Contains(msg, "not a tree object") ||
+ strings.Contains(msg, "relative path syntax")
}
// ListTree returns the immediate children (files and directories) at path