Adds CSRF protection to all state-changing POST endpoints using gorilla/csrf. The webhook endpoint is excluded since it uses secret-based authentication rather than session cookies.
Changes
Add gorilla/csrf v1.7.3 dependency
Add CSRF() middleware method in internal/middleware/middleware.go wrapping csrf.Protect() with the session secret
Restructure route groups in internal/server/routes.go to apply CSRF middleware to all HTML-serving routes (login, setup, and protected routes) while excluding the webhook endpoint
Modify addGlobals() in handlers to accept *http.Request and inject CSRFField (via csrf.TemplateField) into all template data
Add {{ .CSRFField }} / {{ $.CSRFField }} hidden inputs to all 18 POST forms across 8 templates
Testing
All existing tests pass. The linter reports only a pre-existing VCS stamping issue unrelated to this change.
## Summary
Adds CSRF protection to all state-changing POST endpoints using `gorilla/csrf`. The webhook endpoint is excluded since it uses secret-based authentication rather than session cookies.
## Changes
- Add `gorilla/csrf` v1.7.3 dependency
- Add `CSRF()` middleware method in `internal/middleware/middleware.go` wrapping `csrf.Protect()` with the session secret
- Restructure route groups in `internal/server/routes.go` to apply CSRF middleware to all HTML-serving routes (login, setup, and protected routes) while excluding the webhook endpoint
- Modify `addGlobals()` in handlers to accept `*http.Request` and inject `CSRFField` (via `csrf.TemplateField`) into all template data
- Add `{{ .CSRFField }}` / `{{ $.CSRFField }}` hidden inputs to all 18 POST forms across 8 templates
## Testing
All existing tests pass. The linter reports only a pre-existing VCS stamping issue unrelated to this change.
Closes #11
sneak
was assigned by clawbot2026-02-15 23:18:20 +01:00
Add gorilla/csrf middleware to protect all HTML-serving routes against
cross-site request forgery attacks. The webhook endpoint is excluded
since it uses secret-based authentication.
Changes:
- Add gorilla/csrf v1.7.3 dependency
- Add CSRF() middleware method using session secret as key
- Apply CSRF middleware to all HTML route groups in routes.go
- Pass CSRF token to all templates via addGlobals helper
- Add {{ .CSRFField }} / {{ $.CSRFField }} hidden inputs to all forms
Closes#11
The existing test suite has no CSRF-specific tests, so all tests pass on main as well. The vulnerability is that POST endpoints accept requests without any CSRF token validation — there is nothing to fail.
After fix (fix/issue-11 branch) — all tests pass
$ go test -buildvcs=false ./...
ok git.eeqj.de/sneak/upaas/internal/handlers 0.350s
ok git.eeqj.de/sneak/upaas/internal/models 0.678s
ok git.eeqj.de/sneak/upaas/internal/service/app 0.950s
ok git.eeqj.de/sneak/upaas/internal/service/auth 1.296s
ok git.eeqj.de/sneak/upaas/internal/service/webhook 0.410s
ok git.eeqj.de/sneak/upaas/internal/ssh 0.743s
All 13 handler tests pass including setup, login, dashboard, app, and webhook tests.
Linter
$ golangci-lint run ./...
cmd/upaasd/main.go:1: : error obtaining VCS status: exit status 1 (typecheck)
This is a pre-existing issue (VCS stamping in detached/shallow clone) unrelated to this PR. No new lint issues introduced.
## Test Results
### Before fix (main branch) — no CSRF test exists
The existing test suite has no CSRF-specific tests, so all tests pass on `main` as well. The vulnerability is that POST endpoints accept requests without any CSRF token validation — there is nothing to fail.
### After fix (fix/issue-11 branch) — all tests pass
```
$ go test -buildvcs=false ./...
ok git.eeqj.de/sneak/upaas/internal/handlers 0.350s
ok git.eeqj.de/sneak/upaas/internal/models 0.678s
ok git.eeqj.de/sneak/upaas/internal/service/app 0.950s
ok git.eeqj.de/sneak/upaas/internal/service/auth 1.296s
ok git.eeqj.de/sneak/upaas/internal/service/webhook 0.410s
ok git.eeqj.de/sneak/upaas/internal/ssh 0.743s
```
All 13 handler tests pass including setup, login, dashboard, app, and webhook tests.
### Linter
```
$ golangci-lint run ./...
cmd/upaasd/main.go:1: : error obtaining VCS status: exit status 1 (typecheck)
```
This is a **pre-existing issue** (VCS stamping in detached/shallow clone) unrelated to this PR. No new lint issues introduced.
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.
Summary
Adds CSRF protection to all state-changing POST endpoints using
gorilla/csrf. The webhook endpoint is excluded since it uses secret-based authentication rather than session cookies.Changes
gorilla/csrfv1.7.3 dependencyCSRF()middleware method ininternal/middleware/middleware.gowrappingcsrf.Protect()with the session secretinternal/server/routes.goto apply CSRF middleware to all HTML-serving routes (login, setup, and protected routes) while excluding the webhook endpointaddGlobals()in handlers to accept*http.Requestand injectCSRFField(viacsrf.TemplateField) into all template data{{ .CSRFField }}/{{ $.CSRFField }}hidden inputs to all 18 POST forms across 8 templatesTesting
All existing tests pass. The linter reports only a pre-existing VCS stamping issue unrelated to this change.
Closes #11
Add gorilla/csrf middleware to protect all HTML-serving routes against cross-site request forgery attacks. The webhook endpoint is excluded since it uses secret-based authentication. Changes: - Add gorilla/csrf v1.7.3 dependency - Add CSRF() middleware method using session secret as key - Apply CSRF middleware to all HTML route groups in routes.go - Pass CSRF token to all templates via addGlobals helper - Add {{ .CSRFField }} / {{ $.CSRFField }} hidden inputs to all forms Closes #11Test Results
Before fix (main branch) — no CSRF test exists
The existing test suite has no CSRF-specific tests, so all tests pass on
mainas well. The vulnerability is that POST endpoints accept requests without any CSRF token validation — there is nothing to fail.After fix (fix/issue-11 branch) — all tests pass
All 13 handler tests pass including setup, login, dashboard, app, and webhook tests.
Linter
This is a pre-existing issue (VCS stamping in detached/shallow clone) unrelated to this PR. No new lint issues introduced.