security: add CSRF protection to API billing endpoints #13

Open
opened 2026-02-20 11:09:38 +00:00 by Clotho · 0 comments
Member

Issue

Per TODO.md (P1 line 35), routes in routes/api.php use auth middleware but not verified or CSRF tokens for state-changing operations.

Current Behavior

routes/api.php defines billing API endpoints:

Route::middleware(["auth:sanctum"])->group(function () {
    Route::post("/checkout", [CommerceController::class, "checkout"]);
    Route::post("/subscriptions/{id}/cancel", [CommerceController::class, "cancelSubscription"]);
    Route::post("/subscriptions/{id}/pause", [CommerceController::class, "pauseSubscription"]);
    // ...
});

Risk

CSRF attacks: Without CSRF protection, an attacker could:

  • Force authenticated users to cancel their subscriptions
  • Initiate unwanted checkouts
  • Modify payment methods
  • Request refunds

Required Fix

Option 1: Add CSRF middleware (for web-based API)

Route::middleware(["auth:sanctum", "verified"])->group(function () {
    // State-changing endpoints require CSRF token
});

Option 2: Use Sanctum token-based auth (for SPA/mobile)

If these are intended for SPA/mobile apps:

  • Ensure all requests use Sanctum tokens (not cookie-based auth)
  • Document that CSRF protection is not needed due to token-based auth
  • Add rate limiting per token

Option 3: Separate web and API routes

  • Move truly public API endpoints to api.php with token auth
  • Move web-based endpoints to web.php with CSRF protection

Files to Review

  • routes/api.php - Add CSRF middleware or document exemption
  • Middleware/CommerceApiAuth.php - Review authentication strategy
  • CLAUDE.md - Document API authentication requirements

Priority

P1 - Critical: CSRF protection is essential for production security.


Created by discovery scan (issue #2) - References TODO.md P1

## Issue Per TODO.md (P1 line 35), routes in `routes/api.php` use `auth` middleware but not `verified` or CSRF tokens for state-changing operations. ## Current Behavior `routes/api.php` defines billing API endpoints: ```php Route::middleware(["auth:sanctum"])->group(function () { Route::post("/checkout", [CommerceController::class, "checkout"]); Route::post("/subscriptions/{id}/cancel", [CommerceController::class, "cancelSubscription"]); Route::post("/subscriptions/{id}/pause", [CommerceController::class, "pauseSubscription"]); // ... }); ``` ## Risk **CSRF attacks:** Without CSRF protection, an attacker could: - Force authenticated users to cancel their subscriptions - Initiate unwanted checkouts - Modify payment methods - Request refunds ## Required Fix ### Option 1: Add CSRF middleware (for web-based API) ```php Route::middleware(["auth:sanctum", "verified"])->group(function () { // State-changing endpoints require CSRF token }); ``` ### Option 2: Use Sanctum token-based auth (for SPA/mobile) If these are intended for SPA/mobile apps: - Ensure all requests use Sanctum tokens (not cookie-based auth) - Document that CSRF protection is not needed due to token-based auth - Add rate limiting per token ### Option 3: Separate web and API routes - Move truly public API endpoints to `api.php` with token auth - Move web-based endpoints to `web.php` with CSRF protection ## Files to Review - `routes/api.php` - Add CSRF middleware or document exemption - `Middleware/CommerceApiAuth.php` - Review authentication strategy - CLAUDE.md - Document API authentication requirements ## Priority **P1 - Critical:** CSRF protection is essential for production security. --- _Created by discovery scan (issue #2) - References TODO.md P1_
Clotho added the
review
discovery
labels 2026-02-20 11:09:38 +00:00
Charon added
PHP
security
P1
and removed
review
discovery
labels 2026-02-20 12:17:12 +00:00
Clotho was assigned by Charon 2026-02-20 12:20:52 +00:00
Charon added the
agent-ready
label 2026-02-21 01:31:40 +00:00
Sign in to join this conversation.
No description provided.