Add API CSRF protection via X-Requested-With header (closes #112) #116
No reviewers
Labels
No Label
bug
duplicate
enhancement
help wanted
invalid
merge-ready
merge-ready
needs-checks
needs-checks
needs-rebase
needs-rebase
needs-review
needs-review
needs-rework
needs-rework
notplanned
question
wontfix
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: sneak/upaas#116
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "fix/112-api-csrf-protection"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Fixes #112 — API v1 CSRF vulnerability.
The API v1 endpoints use cookie-based session auth without CSRF protection. A malicious website could make authenticated requests (delete apps, trigger deploys, read secrets) via the user's session cookie.
Changes
APICSRFProtectionmiddleware — requiresX-Requested-Withheader on state-changing requests (POST/PUT/DELETE/PATCH). Browsers cannot send custom headers cross-origin without CORS preflight, blocking CSRF.SameSite=Strict— upgraded fromLaxas defense-in-depth.X-Requested-Withfor legitimate cross-origin API clients.make checkoutputAll checks pass with zero failures.
Self-Review
Approach: Requires
X-Requested-Withcustom header on non-safe API methods. Browsers cannot send custom headers cross-origin without CORS preflight approval, which prevents CSRF. This is the same pattern used by frameworks like Django REST and Angular.Reviewed items:
/api/v1route group level (covers all API endpoints including login)X-Requested-Withfor legitimate cross-origin clientsSameSite=Strictas defense-in-depth (wasLax)make checkpasses with zero failuresNote: The
X-Requested-Withheader requirement applies to the login endpoint too (POST /api/v1/login). This is intentional — API clients must include the header. The web UI login form uses the HTML routes (/login), not the API.Pull request closed