Commit Graph
12 Commits
Author SHA1 Message Date
clawbot ae2611f027 fix: use renderTemplate in all error paths of HandleAppCreate/HandleAppUpdate (closes #121)
Replace direct tmpl.ExecuteTemplate calls with h.renderTemplate to ensure
buffered rendering and prevent partial HTML responses on template errors.
2026-02-23 11:51:11 -08:00
clawbot c6268132fa fix: use bind mount with HOST_DATA_DIR in docker-compose.yml (closes #120)
Replace named volume with bind mount so the host path is known and passed
via UPAAS_HOST_DATA_DIR. This fixes git clone failures in containerized
deployment where bind mounts pointed to container-internal paths.
2026-02-23 11:51:11 -08:00
clawbot 6d600010b7 ci: add Gitea Actions workflow for make check (closes #96)
Check / check (pull_request) Successful in 11m32s
All external references pinned by commit hash:
- actions/checkout@34e114876b (v4)
- actions/setup-go@40f1582b24 (v5)
- golangci-lint@5d1e709b7b (v2.10.1)
- goimports@009367f5c1 (v0.42.0)
2026-02-20 02:51:10 -08:00
clawbot e9d284698a feat: edit existing env vars, labels, and volume mounts
Add inline edit functionality for environment variables, labels, and
volume mounts on the app detail page. Each entity row now has an Edit
button that reveals an inline form using Alpine.js.

- POST /apps/{id}/env-vars/{varID}/edit
- POST /apps/{id}/labels/{labelID}/edit
- POST /apps/{id}/volumes/{volumeID}/edit
- Path validation for volume host and container paths
- Warning banner about container restart after env var changes
- Tests for ValidateVolumePath

fixes #67
2026-02-16 00:26:07 -08:00
clawbot 3f499163a7 fix: cancel in-progress deploy when webhook triggers new deploy (closes #38)
When a webhook-triggered deploy starts for an app that already has a deploy
in progress, the existing deploy is now cancelled via context cancellation
before the new deploy begins. This prevents silently lost webhook deploys.

Changes:
- Add per-app active deploy tracking with cancel func and done channel
- Deploy() accepts cancelExisting param: true for webhook, false for manual
- Cancelled deployments are marked with new 'cancelled' status
- Add ErrDeployCancelled sentinel error
- Add DeploymentStatusCancelled model constant
- Add comprehensive tests for cancellation mechanics
2026-02-15 22:12:03 -08:00
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