在 CORS 响应中回显 Origin 标头而不重新检查 AWS Lambda 中的白名单是否安全?

问题描述 投票:0回答:1

我们正在使用 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 请求期间,这种方法安全吗? 我们应该在这里考虑任何潜在的陷阱或最佳实践吗?

感谢您的建议!

javascript amazon-web-services aws-lambda cors
1个回答
0
投票

我相信您也应该在实际请求中验证来源。显然,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' }),
  };
};
© www.soinside.com 2019 - 2024. All rights reserved.