Commit Graph
7 Commits
Author SHA1 Message Date
clawbot cdd7e3fd3a fix: set DestroySession MaxAge to -1 instead of -1*time.Second (closes #39)
The gorilla/sessions MaxAge field expects seconds, not nanoseconds.
Previously MaxAge was set to -1000000000 (-1 * time.Second in nanoseconds),
which worked by accident since any negative value deletes the cookie.
Changed to the conventional value of -1.
2026-02-15 22:07:57 -08:00
clawbot b1a6fd5fca fix: only trust proxy headers from RFC1918/loopback sources (closes #44)
realIP() now parses RemoteAddr and checks if the source IP is in
RFC1918 (10/8, 172.16/12, 192.168/16), loopback (127/8), or IPv6
ULA/loopback ranges before trusting X-Real-IP or X-Forwarded-For
headers. Public source IPs have headers ignored (fail closed).

This prevents attackers from spoofing X-Forwarded-For to bypass
the login rate limiter.
2026-02-15 22:01:54 -08:00
clawbot 763e722607 fix: prevent setup endpoint race condition (closes #26)
Add mutex and INSERT ON CONFLICT to CreateUser to prevent TOCTOU race
where concurrent requests could create multiple admin users.

Changes:
- Add sync.Mutex to auth.Service to serialize CreateUser calls
- Add models.CreateUserAtomic using INSERT ... ON CONFLICT(username) DO NOTHING
- Check RowsAffected to detect conflicts at the DB level (defense-in-depth)
- Add concurrent race condition test (10 goroutines, only 1 succeeds)

The existing UNIQUE constraint on users.username was already in place.
This fix adds the application-level protection (items 1 & 2 from #26).
2026-02-15 21:35:16 -08:00
clawbot 7c0278439d fix: prevent command injection in git clone arguments (closes #18)
- Validate branch names against ^[a-zA-Z0-9._/\-]+$
- Validate commit SHAs against ^[0-9a-f]{40}$
- Pass repo URL, branch, and SHA via environment variables instead of
  interpolating into shell script string
- Add comprehensive tests for validation and injection rejection
2026-02-15 21:33:02 -08:00
clawbot ef0786c4b4 fix: extract real client IP from proxy headers (X-Real-IP / X-Forwarded-For)
Behind a reverse proxy like Traefik, RemoteAddr always contains the
proxy's IP. Add realIP() helper that checks X-Real-IP first, then the
first entry of X-Forwarded-For, falling back to RemoteAddr.

Update both LoginRateLimit and Logging middleware to use realIP().
Add comprehensive tests for the new function.

Fixes #12
2026-02-15 21:14:12 -08:00
clawbot 867cdf01ab fix: add ownership verification on env var, label, volume, and port deletion
Verify that the resource's AppID matches the URL path app ID before
allowing deletion. Without this check, any authenticated user could
delete resources belonging to any app by providing the target resource's
ID in the URL regardless of the app ID in the path (IDOR vulnerability).

Closes #19
2026-02-15 21:02:46 -08:00
clawbot 6475389280 test: add IDOR tests for resource deletion ownership verification
Tests demonstrate that env vars, labels, volumes, and ports can be
deleted via another app's URL path without ownership checks.

All 4 tests fail, confirming the vulnerability described in #19.
2026-02-15 21:00:41 -08:00