Enhance CORS middleware to include referer checks and improve security for whitelisted domains
All checks were successful
Deploy Production (ss-tools.crewsportswear.app) / deploy (push) Successful in 1m5s
All checks were successful
Deploy Production (ss-tools.crewsportswear.app) / deploy (push) Successful in 1m5s
This commit is contained in:
@@ -15,13 +15,17 @@ if (process.env.USE_SSL === 'true') {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CORS Configuration
|
// CORS Configuration - Whitelisted domains that can access the API
|
||||||
const allowedOrigins = [
|
const allowedOrigins = [
|
||||||
'http://uniformnetwork.com',
|
|
||||||
'http://localhost',
|
|
||||||
'https://crewsportswear.com',
|
'https://crewsportswear.com',
|
||||||
|
'https://www.crewsportswear.com',
|
||||||
'https://crewsportswear.app',
|
'https://crewsportswear.app',
|
||||||
'https://merchbay.com'
|
'https://dev-crew.crewsportswear.app',
|
||||||
|
'https://merchbay.com',
|
||||||
|
'https://www.merchbay.com',
|
||||||
|
'https://dev.merchbay.app',
|
||||||
|
'http://localhost',
|
||||||
|
'http://localhost:8080'
|
||||||
];
|
];
|
||||||
|
|
||||||
// Screenshot Configuration
|
// Screenshot Configuration
|
||||||
|
|||||||
@@ -1,17 +1,46 @@
|
|||||||
const { allowedOrigins } = require('../config/config');
|
const { allowedOrigins } = require('../config/config');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CORS middleware
|
* CORS and Security middleware
|
||||||
* Handles Cross-Origin Resource Sharing for allowed domains
|
* Only allows requests from whitelisted domains
|
||||||
*/
|
*/
|
||||||
function corsMiddleware(req, res, next) {
|
function corsMiddleware(req, res, next) {
|
||||||
const origin = req.headers.origin;
|
const origin = req.headers.origin;
|
||||||
|
const referer = req.headers.referer;
|
||||||
|
|
||||||
if (allowedOrigins.indexOf(origin) > -1) {
|
// Check if origin is allowed
|
||||||
|
const isOriginAllowed = origin && allowedOrigins.indexOf(origin) > -1;
|
||||||
|
|
||||||
|
// Check if referer matches allowed domains
|
||||||
|
const isRefererAllowed = referer && allowedOrigins.some(allowed => {
|
||||||
|
try {
|
||||||
|
const refererHost = new URL(referer).origin;
|
||||||
|
return refererHost === allowed || referer.startsWith(allowed);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Allow if origin OR referer is whitelisted
|
||||||
|
// Also allow health check endpoint without restrictions
|
||||||
|
if (req.path === '/health') {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isOriginAllowed && !isRefererAllowed) {
|
||||||
|
console.warn(`Blocked request from Origin: ${origin || 'none'}, Referer: ${referer || 'none'}`);
|
||||||
|
return res.status(403).json({
|
||||||
|
error: 'Forbidden',
|
||||||
|
message: 'Access denied. This API is restricted to authorized domains only.'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set CORS headers for allowed origin
|
||||||
|
if (isOriginAllowed) {
|
||||||
res.setHeader('Access-Control-Allow-Origin', origin);
|
res.setHeader('Access-Control-Allow-Origin', origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
|
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
||||||
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
|
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
|
||||||
res.setHeader('Access-Control-Allow-Credentials', true);
|
res.setHeader('Access-Control-Allow-Credentials', true);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user