refactor(csrf): replace ZEN_APP_URL with NEXT_PUBLIC_URL env vars
Replace the single `ZEN_APP_URL` environment variable with the existing `NEXT_PUBLIC_URL` and `NEXT_PUBLIC_URL_DEV` variables for CSRF origin resolution. - Add `resolveAppUrl()` helper that prefers `NEXT_PUBLIC_URL_DEV` in development and falls back to `NEXT_PUBLIC_URL` in production - Update `passesCsrfCheck()` to use the new helper - Update error log messages to reference the new variable names
This commit is contained in:
+21
-6
@@ -30,6 +30,22 @@ import { handleGetFile } from './handlers/storage.js';
|
||||
// Get cookie name from environment or use default
|
||||
const COOKIE_NAME = getSessionCookieName();
|
||||
|
||||
/**
|
||||
* Resolve the canonical application URL from environment variables.
|
||||
*
|
||||
* Priority:
|
||||
* 1. NEXT_PUBLIC_URL_DEV — used when NODE_ENV=development
|
||||
* 2. NEXT_PUBLIC_URL — used in production
|
||||
*
|
||||
* @returns {string|null}
|
||||
*/
|
||||
function resolveAppUrl() {
|
||||
if (process.env.NODE_ENV === 'development' && process.env.NEXT_PUBLIC_URL_DEV) {
|
||||
return process.env.NEXT_PUBLIC_URL_DEV;
|
||||
}
|
||||
return process.env.NEXT_PUBLIC_URL || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that state-mutating requests (POST/PUT/PATCH/DELETE) originate from
|
||||
* the expected application origin, blocking cross-site request forgery.
|
||||
@@ -37,9 +53,8 @@ const COOKIE_NAME = getSessionCookieName();
|
||||
* The check is skipped for safe HTTP methods (GET, HEAD, OPTIONS) which must
|
||||
* not cause side-effects per RFC 7231.
|
||||
*
|
||||
* If ZEN_APP_URL is not configured the check is bypassed with a warning — this
|
||||
* guards against locking out misconfigured deployments while making the missing
|
||||
* configuration visible in logs.
|
||||
* The expected origin is resolved from environment variables (see resolveAppUrl).
|
||||
* If no URL is configured the check denies the request and logs an error.
|
||||
*
|
||||
* @param {Request} request
|
||||
* @returns {boolean} true if the request passes CSRF validation
|
||||
@@ -48,9 +63,9 @@ function passesCsrfCheck(request) {
|
||||
const safeMethods = new Set(['GET', 'HEAD', 'OPTIONS']);
|
||||
if (safeMethods.has(request.method)) return true;
|
||||
|
||||
const appUrl = process.env.ZEN_APP_URL;
|
||||
const appUrl = resolveAppUrl();
|
||||
if (!appUrl) {
|
||||
console.error('[ZEN CSRF] ZEN_APP_URL is not set — CSRF origin check is ENFORCED DENY. Configure this variable immediately.');
|
||||
console.error('[ZEN CSRF] No app URL configured (NEXT_PUBLIC_URL_DEV / NEXT_PUBLIC_URL) — CSRF check denied.');
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -58,7 +73,7 @@ function passesCsrfCheck(request) {
|
||||
try {
|
||||
expectedOrigin = new URL(appUrl).origin;
|
||||
} catch {
|
||||
console.error('[ZEN CSRF] ZEN_APP_URL is not a valid URL:', appUrl);
|
||||
console.error('[ZEN CSRF] Configured app URL is not valid:', appUrl);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user