fix(csrf): enable newsletter subscription from mobile

CRITICAL FIX: Newsletter subscription was returning "Forbidden" error
because the CSRF protection was incorrectly configured.

Root cause:
- CSRF cookie was set with httpOnly: true
- JavaScript cannot read httpOnly cookies
- Frontend couldn't extract token to send in X-CSRF-Token header
- Double-submit CSRF pattern requires client to read the cookie

Changes:
- csrf-protection.middleware.js: Set httpOnly: false (required for double-submit pattern)
- blog.js: Extract CSRF token from cookie and include in X-CSRF-Token header

Security Note: This is the correct implementation per OWASP guidelines
for double-submit cookie CSRF protection. The cookie is still protected
by SameSite: strict and domain restrictions.

Fixes: #newsletter-subscription-forbidden-mobile
This commit is contained in:
TheFlow 2025-10-24 16:42:56 +13:00
parent ca8edb383b
commit cfc4347e9b
2 changed files with 9 additions and 2 deletions

View file

@ -571,10 +571,17 @@ function setupNewsletterModal() {
submitBtn.textContent = 'Subscribing...';
try {
// Get CSRF token from cookie
const csrfToken = document.cookie
.split('; ')
.find(row => row.startsWith('csrf-token='))
?.split('=')[1];
const response = await fetch('/api/newsletter/subscribe', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken || ''
},
body: JSON.stringify({
email,

View file

@ -79,7 +79,7 @@ function setCsrfToken(req, res, next) {
const isSecure = req.secure || req.headers['x-forwarded-proto'] === 'https';
res.cookie('csrf-token', token, {
httpOnly: true,
httpOnly: false, // Must be false for double-submit pattern (client needs to read it)
secure: isSecure && process.env.NODE_ENV === 'production',
sameSite: 'strict',
maxAge: 24 * 60 * 60 * 1000 // 24 hours