Surveyed 2026-08-07: golangci-lint 2.12.2 reports one G703: Path traversal via taint analysis finding at internal/handlers/app.go:629 — http.ServeFile called with a logPath derived from request data:
Remediation: before serving, canonicalize the path
(filepath.Clean, resolving against the configured data directory)
and verify containment — the resolved path must be inside the deploy
log directory (e.g. filepath.Rel result must not start with ..).
Return 404 on violation. Do not use //nolint.
Definition of done:
make lint (golangci-lint ≥ 2.12) reports zero G703 findings
a unit test exercises the handler with a traversal-shaped input
(e.g. an id containing ..) and asserts it is rejected
legitimate log download still works (make test passes)
make fmt run before commit; TODO.md updated per the repo workflow
lands via PR from a feature branch off main
Surveyed 2026-08-07: golangci-lint 2.12.2 reports one
`G703: Path traversal via taint analysis` finding at
`internal/handlers/app.go:629` — `http.ServeFile` called with a
`logPath` derived from request data:
```go
filename := filepath.Base(logPath)
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.Header().Set("Content-Disposition", "attachment; filename=\""+filename+"\"")
http.ServeFile(writer, request, logPath)
```
Remediation: before serving, canonicalize the path
(`filepath.Clean`, resolving against the configured data directory)
and verify containment — the resolved path must be inside the deploy
log directory (e.g. `filepath.Rel` result must not start with `..`).
Return 404 on violation. Do not use `//nolint`.
Definition of done:
- `make lint` (golangci-lint ≥ 2.12) reports zero `G703` findings
- a unit test exercises the handler with a traversal-shaped input
(e.g. an id containing `..`) and asserts it is rejected
- legitimate log download still works (`make test` passes)
- `make fmt` run before commit; `TODO.md` updated per the repo workflow
- lands via PR from a feature branch off `main`
clawbot
added this to the 1.1.0 milestone 2026-08-07 18:40:39 +02:00
Fixed. The log download handler now opens the log file through an os.Root confined to the deploy log directory (Root.Open rejects any path that escapes the root) instead of passing the request-derived path to http.ServeFile; the opened file is streamed with http.ServeContent, and traversal attempts return 404. A string-only filepath.Rel containment check did not clear the gosec taint analyzer, so the os.Root boundary is used; no //nolint or #nosec. Added GetLogDir on the deploy service and two handler tests (legitimate download succeeds; an app name containing .. is rejected).
Note: the DoD said branch off main; per the repo branch workflow the PR targets next instead.
Model: opus-4-8
Fixed. The log download handler now opens the log file through an `os.Root` confined to the deploy log directory (`Root.Open` rejects any path that escapes the root) instead of passing the request-derived path to `http.ServeFile`; the opened file is streamed with `http.ServeContent`, and traversal attempts return 404. A string-only `filepath.Rel` containment check did not clear the gosec taint analyzer, so the `os.Root` boundary is used; no `//nolint` or `#nosec`. Added `GetLogDir` on the deploy service and two handler tests (legitimate download succeeds; an app name containing `..` is rejected).
PR: https://git.eeqj.de/sneak/upaas/pulls/194
Note: the DoD said branch off `main`; per the repo branch workflow the PR targets `next` instead.
Model: opus-4-8
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Surveyed 2026-08-07: golangci-lint 2.12.2 reports one
G703: Path traversal via taint analysisfinding atinternal/handlers/app.go:629—http.ServeFilecalled with alogPathderived from request data:Remediation: before serving, canonicalize the path
(
filepath.Clean, resolving against the configured data directory)and verify containment — the resolved path must be inside the deploy
log directory (e.g.
filepath.Relresult must not start with..).Return 404 on violation. Do not use
//nolint.Definition of done:
make lint(golangci-lint ≥ 2.12) reports zeroG703findings(e.g. an id containing
..) and asserts it is rejectedmake testpasses)make fmtrun before commit;TODO.mdupdated per the repo workflowmainclawbot referenced this issue2026-09-03 18:29:27 +02:00
clawbot referenced this issue2026-09-03 18:29:56 +02:00
Fixed. The log download handler now opens the log file through an
os.Rootconfined to the deploy log directory (Root.Openrejects any path that escapes the root) instead of passing the request-derived path tohttp.ServeFile; the opened file is streamed withhttp.ServeContent, and traversal attempts return 404. A string-onlyfilepath.Relcontainment check did not clear the gosec taint analyzer, so theos.Rootboundary is used; no//nolintor#nosec. AddedGetLogDiron the deploy service and two handler tests (legitimate download succeeds; an app name containing..is rejected).PR: #194
Note: the DoD said branch off
main; per the repo branch workflow the PR targetsnextinstead.Model: opus-4-8