我们正在使用 AWS Lambda 函数开发 API。我们有一个 Lambda 来处理 CORS 预检检查的所有 OPTIONS 请求。此 Lambda 根据白名单验证来源,如果有效,则响应:
{
'Access-Control-Allow-Origin': 'https://exampledomain.com',
'Access-Control-Allow-Credentials': 'true'
}
对于实际的 API 请求(例如,POST 或 GET),我们还希望在响应中包含相同的标头,以允许浏览器正确处理请求。但是,我们想知道在实际响应中简单地回显传入请求的 Origin 值而不是执行另一个白名单验证是否安全。
例如:
选项请求:
根据白名单检查来源。 如果有效,Lambda 将响应 200 状态和 CORS 标头。
实际请求(例如POST):
我们没有重新检查 Origin,而是在 Access-Control-Allow-Origin 标头中回显 Origin 值,如下所示:
{
'Access-Control-Allow-Origin': request.headers.origin,
'Access-Control-Allow-Credentials': 'true'
}
我的问题是:
假设白名单验证发生在 OPTIONS 请求期间,这种方法安全吗? 我们应该在这里考虑任何潜在的陷阱或最佳实践吗?
感谢您的建议!
我相信您也应该在实际请求中验证来源。显然,HTTP 请求是无状态的,并且 OPTIONS 预检请求无论如何都不会链接到实际请求。这为中间人攻击提供了可能性。
理论上,任何人都可以恶意发送正确的标头到您的实际 HTTP 处理程序(GET、POST 等...)。
鉴于上述陈述,我宁愿在 lambda 中处理选项和实际请求,以确保您每次都检查白名单来源:
exports.handler = async (event) => {
const whitelist = ['https://exampledomain.com', 'https://anotherdomain.com'];
const origin = event.headers.origin || event.headers.Origin;
const responseHeaders = {
'Content-Type': 'application/json',
};
// Validate Origin
if (whitelist.includes(origin)) {
responseHeaders['Access-Control-Allow-Origin'] = origin;
responseHeaders['Access-Control-Allow-Credentials'] = 'true';
} else {
// If Origin is not allowed, deny the request
return {
statusCode: 403,
headers: responseHeaders,
body: JSON.stringify({ message: 'Origin not allowed' }),
};
}
// Handle Preflight Request
if (event.httpMethod === 'OPTIONS') {
responseHeaders['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS';
responseHeaders['Access-Control-Allow-Headers'] = 'Content-Type, Authorization';
responseHeaders['Access-Control-Max-Age'] = '3600'; // Cache for 1 hour
return {
statusCode: 200,
headers: responseHeaders,
body: '',
};
}
// Handle Actual Request
// Your business logic here
return {
statusCode: 200,
headers: responseHeaders,
body: JSON.stringify({ message: 'Success' }),
};
};