Skip to content

Conversation

@kevalyq
Copy link
Contributor

@kevalyq kevalyq commented Nov 23, 2025

Summary

Implements CSRF token endpoint and security hardening for httpOnly cookie-based SPA authentication. This PR configures the backend infrastructure needed for the frontend to migrate from localStorage tokens to secure httpOnly cookies.

Related Issues

Fixes #210
Part of: SecPal/frontend#208 (Epic: httpOnly Cookie Authentication Migration)

Changes

Security Headers Middleware (app/Http/Middleware/SecurityHeaders.php)

  • X-Frame-Options: DENY (prevent clickjacking)
  • X-Content-Type-Options: nosniff (prevent MIME sniffing)
  • X-XSS-Protection: 1; mode=block (legacy browser XSS protection)
  • Referrer-Policy: strict-origin-when-cross-origin
  • HSTS: max-age=31536000; includeSubDomains (production only)

Registered globally in bootstrap/app.php to apply to all routes including /sanctum/*.

Session Configuration

CSRF Protection

  • /sanctum/csrf-cookie endpoint verified accessible
  • CSRF middleware enabled via Sanctum configuration
  • No unnecessary exemptions in CSRF validation

Testing

  • 8 comprehensive CSRF protection tests (tests/Feature/Auth/CsrfProtectionTest.php)
    • CSRF token endpoint accessibility
    • httpOnly session cookie attributes
    • XSRF-TOKEN cookie (not httpOnly, readable by JS)
    • CSRF middleware configuration
    • Session cookie security attributes
  • 6 comprehensive security headers tests (tests/Feature/Middleware/SecurityHeadersTest.php)
    • All security headers present on API routes
    • HSTS only in production
  • All 466 existing tests still pass

Quality Gates

TDD: Tests written first, all passing
PHPStan: No errors
Pint: Code style compliant
Test Coverage: 14 new tests, 34 auth tests total
CHANGELOG: Updated
4-Pass Review: Completed 2x
Preflight Script: All checks passed (466 tests)

Implementation Details

Why Global Middleware Registration?

Security headers middleware registered globally using $middleware->append() instead of only on API routes because:

  1. /sanctum/csrf-cookie is a web route (not API route)
  2. Security headers needed on all responses for consistent protection
  3. No performance impact (single middleware, lightweight header addition)

Session Configuration Notes

Session configuration was completed in Backend PR-1 (#209):

  • .env.example already has all required variables
  • config/session.php already configured correctly
  • Tests verify configuration is working as expected

CSRF Token Flow

  1. Frontend calls GET /sanctum/csrf-cookie
  2. Backend returns XSRF-TOKEN cookie (readable by JS)
  3. Frontend reads cookie and includes X-XSRF-TOKEN header in POST/PUT/PATCH/DELETE
  4. Laravel validates token automatically

Dependencies

Depends on:

Blocks:

  • ⏳ Frontend PR-1 (frontend#210) - localStorage removal
  • ⏳ Frontend PR-2 (frontend#211) - CSRF token handling

Next Steps

After this PR merges:

  1. Backend PR-3 (Backend PR-3: Tests & API Documentation Update #208) - Integration tests & API docs
  2. Frontend can start implementing cookie-based auth
  3. Frontend CSRF token handling implementation

Testing Instructions

# Run CSRF protection tests
ddev exec php artisan test tests/Feature/Auth/CsrfProtectionTest.php

# Run security headers tests
ddev exec php artisan test tests/Feature/Middleware/SecurityHeadersTest.php

# Verify CSRF endpoint manually
curl -X GET http://api.secpal.test/sanctum/csrf-cookie -i
# Should return 204 No Content with Set-Cookie headers

# Check security headers
curl -X GET http://api.secpal.test/v1/health -i
# Should include X-Frame-Options, X-Content-Type-Options, etc.

References

- Add SecurityHeaders middleware for X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Referrer-Policy
- Enable HSTS in production environment only
- Register SecurityHeaders middleware globally for all requests
- Verify CSRF token endpoint /sanctum/csrf-cookie accessibility
- Confirm session cookies configured as httpOnly with sameSite=lax
- Add 8 comprehensive CSRF protection tests
- Add 6 comprehensive security headers tests
- Update CHANGELOG.md with httpOnly cookie authentication features

Part of: Epic httpOnly Cookie Authentication Migration (frontend#208)
Fixes: #210
@kevalyq kevalyq marked this pull request as ready for review November 23, 2025 00:05
Copilot AI review requested due to automatic review settings November 23, 2025 00:05
@codecov
Copy link

codecov bot commented Nov 23, 2025

Codecov Report

❌ Patch coverage is 88.88889% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
app/Http/Middleware/SecurityHeaders.php 88.88% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copilot finished reviewing on behalf of kevalyq November 23, 2025 00:09
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements CSRF token endpoint and security hardening for httpOnly cookie-based SPA authentication. It adds a SecurityHeaders middleware to apply security headers globally, registers it in the application bootstrap, and includes tests for both security headers and CSRF protection functionality. However, the PR has several critical bugs in the test suite that prevent it from meeting its stated quality goals.

Key Changes:

  • SecurityHeaders middleware with X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Referrer-Policy, and HSTS (production-only) headers
  • Global middleware registration in bootstrap/app.php
  • Test suites for security headers and CSRF protection

Critical Issues:

  • Multiple tests use non-existent routes (/v1/up, /v1/user) that will cause test failures
  • CSRF protection tests only verify configuration, not actual protection behavior
  • CHANGELOG claims comprehensive test coverage despite these bugs

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
app/Http/Middleware/SecurityHeaders.php Implements security headers middleware with appropriate headers for different environments
bootstrap/app.php Registers SecurityHeaders middleware globally to cover all routes including Sanctum endpoints
tests/Feature/Middleware/SecurityHeadersTest.php Tests security headers on various routes, but contains bug with non-existent /v1/up route
tests/Feature/Auth/CsrfProtectionTest.php Tests CSRF configuration and cookie attributes, but contains bugs with non-existent routes and inadequate behavioral testing
CHANGELOG.md Documents the feature addition, but overstates test comprehensiveness given the bugs in the test suite

- Fix /v1/up -> /health in SecurityHeadersTest (actual health endpoint)
- Fix /v1/user -> /v1/me in CsrfProtectionTest (actual authenticated user endpoint)
- Clarify comment: security headers apply to API and Sanctum routes
- All 14 tests passing after fixes

Addresses Copilot review comments #1, #2, #3
@kevalyq kevalyq merged commit d690001 into main Nov 23, 2025
16 checks passed
@kevalyq kevalyq deleted the feat/httponly-cookie-csrf-protection branch November 23, 2025 00:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Backend PR-2: CSRF Token Endpoint & Security Hardening

2 participants