Import source: backend/src/middleware/csrf
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,34 @@
|
|||||||
|
import type { RequestHandler } from 'express';
|
||||||
|
import { env } from '../config/env.js';
|
||||||
|
import { HttpError } from './errorHandler.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strict origin-based CSRF protection for mutating HTTP requests.
|
||||||
|
* Compares request Origin/Referer against the configured frontendUrl.
|
||||||
|
*/
|
||||||
|
export const csrfProtection: RequestHandler = (req, _res, next) => {
|
||||||
|
// Safe methods do not modify state and are exempt from CSRF checks
|
||||||
|
if (['GET', 'HEAD', 'OPTIONS'].includes(req.method)) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
const origin = (req.headers.origin || req.headers.referer) as string;
|
||||||
|
if (!origin) {
|
||||||
|
// If no origin/referer header is sent (e.g. direct curl/scripts), we permit it
|
||||||
|
// because CSRF requires a browser to automatically attach credentials (cookies)
|
||||||
|
// on cross-origin requests. Direct API consumers sending keys/tokens are not susceptible to CSRF.
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const originUrl = new URL(origin);
|
||||||
|
const frontendUrl = new URL(env.frontendUrl);
|
||||||
|
if (originUrl.host !== frontendUrl.host) {
|
||||||
|
throw new HttpError(403, 'CSRF_DETECTED', 'Security policy violation: cross-site request blocked');
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
throw new HttpError(403, 'CSRF_DETECTED', 'Security policy violation: malformed origin identifier');
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user