HIGH: Missing ownership verification on env var, label, volume, and port deletion #19

Closed
opened 2026-02-16 05:47:10 +01:00 by clawbot · 1 comment
Collaborator

Bug

Files:

  • internal/handlers/app.goHandleEnvVarDelete(), HandleLabelDelete(), HandleVolumeDelete(), HandlePortDelete()

Severity: HIGH — Authorization bypass / data integrity

Description

The delete handlers for env vars, labels, volumes, and ports look up the resource by its own ID but never verify that the resource belongs to the app specified in the URL path. For example in HandleEnvVarDelete:

appID := chi.URLParam(request, "id")
envVarIDStr := chi.URLParam(request, "envID")
// ...
envVar, findErr := models.FindEnvVar(request.Context(), h.db, envVarID)
if findErr != nil || envVar == nil {
    http.NotFound(writer, request)
    return
}
deleteErr := envVar.Delete(request.Context())

The appID from the URL is never compared to envVar.AppID. An authenticated user can delete any env var/label/volume/port belonging to any app by simply providing the target resource's ID in the URL, regardless of which app ID is in the path.

Suggested Fix

Add ownership verification after finding the resource:

if envVar.AppID != appID {
    http.NotFound(writer, request)
    return
}

Apply the same pattern to all four delete handlers.

## Bug **Files:** - `internal/handlers/app.go` — `HandleEnvVarDelete()`, `HandleLabelDelete()`, `HandleVolumeDelete()`, `HandlePortDelete()` **Severity:** HIGH — Authorization bypass / data integrity ### Description The delete handlers for env vars, labels, volumes, and ports look up the resource by its own ID but never verify that the resource belongs to the app specified in the URL path. For example in `HandleEnvVarDelete`: ```go appID := chi.URLParam(request, "id") envVarIDStr := chi.URLParam(request, "envID") // ... envVar, findErr := models.FindEnvVar(request.Context(), h.db, envVarID) if findErr != nil || envVar == nil { http.NotFound(writer, request) return } deleteErr := envVar.Delete(request.Context()) ``` The `appID` from the URL is never compared to `envVar.AppID`. An authenticated user can delete any env var/label/volume/port belonging to any app by simply providing the target resource's ID in the URL, regardless of which app ID is in the path. ### Suggested Fix Add ownership verification after finding the resource: ```go if envVar.AppID != appID { http.NotFound(writer, request) return } ``` Apply the same pattern to all four delete handlers.
Owner

@claw - make a new branch, write a failing test, commit and push it, then implement the fix and verify it makes the test pass without changes to the test. then create a PR and assign it to me. review the PR changes with another agent and have it leave its review in a comment on the PR.

@claw - make a new branch, write a failing test, commit and push it, then implement the fix and verify it makes the test pass without changes to the test. then create a PR and assign it to me. review the PR changes with another agent and have it leave its review in a comment on the PR.
sneak closed this issue 2026-02-16 06:12:53 +01:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: sneak/upaas#19
No description provided.