Jie*_*eng 7 lambda amazon-web-services cors aws-api-gateway api-gateway
我想为多个来源实现CORS,我知道我需要通过lambda函数这样做,因为我不能通过MOCK方法这样做
exports.handler = async (event) => {
const corsUrls = (process.env.CORS_URLS || '').split(',')
const requestOrigin = (event.headers && event.headers.origin) || ''
if (corsUrls.includes(requestOrigin)) {
return {
statusCode: 204,
headers: {
"Access-Control-Allow-Headers": 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Requested-With',
'Access-Control-Allow-Origin': requestOrigin,
'Access-Control-Allow-Methods': 'POST,DELETE,OPTIONS'
}
}
}
return {
statusCode: 403,
body: JSON.stringify({
status: 'Invalid CORS origin'
})
}
}
Run Code Online (Sandbox Code Playgroud)
首先,上面看起来好吗?然后我从标题获得起源event.headers.origin.但我发现我可以手动设置该标题以"绕过"cors.有没有可靠的方法来检测原始域?
首先,上面的内容看起来没问题吗?
乍一看,您的代码对我来说看起来不错,除了您的观点之外But I find that I can just set that header manually to "bypass" cors,我没有发现它有任何重大问题。
然后我从 headers event.headers.origin 获取 origin。但我发现我可以手动设置该标头来“绕过”cors。有没有可靠的方法来检测源域?
您当前使用的代码是我能想到的如何检测原始域的唯一方法。尽管正如您所说,您可以手动设置该标头,并且不能保证标头是正确或有效的。它不应该被用作安全信任层。对于浏览器,它们限制如何设置此标头(请参阅禁止的标头名称)。但是,如果您控制 HTTP 客户端(例如,curl、postman等),您可以轻松发送您想要的任何标头。没有任何技术可以阻止我向您的网络服务器发送具有任何我想要的值的任何标头。
因此,归根结底,这可能不是一个大问题。如果有人篡改该标头,他们就会面临安全风险和意外行为。有很多方法可以绕过 CORS,比如这样,或者这样,或者也许这样。因此,尽管您尽了最大努力来强制实施,但最终还是有可能绕过 CORS。尽管所有这些技巧都是黑客,普通用户可能不会使用。与更改原始标头相同,普通用户不太可能完成。
您还可以研究一些其他技巧,以尝试更多地执行它。您可以查看引用标头,看看它是否与原始标头相同。同样,可以为任何标头发送任何内容,但这会使其变得更加困难并强制执行您想要的更多内容。
如果您假设您的原始标头应始终等于 API Gateway API 的域,那么您可以查看的另一件事是event.requestContextAPI Gateway 为您提供的对象。该对象附加了resourceId、stage、accountId、apiId和其他一些有趣的属性。您可以考虑构建一个系统来验证这些值,并根据这些值确定 API Gateway 中的哪个 API 正在发出请求。这可能需要确保您已将每个域分离到单独的 API 网关 API 中。
无论如何,我不认为 中的这些值event.requestContext可能会被篡改,因为 AWS 在将事件对象传递给您之前设置了它们。它们源自 AWS,用户不易篡改(除非请求的整个构成发生变化)。当然,与仅随请求一起发送的标头相比,防篡改性要差得多,AWS 会将其传递给您。
当然,您可以将多个解决方案组合在一起,以创建一个更能执行您的策略的解决方案。请记住,安全性是一个范围,因此您能在该范围内走多远取决于您。
我还鼓励您记住 CORS 并不完全是为了隐藏互联网上的信息。我分享的关于如何使用简单的后端系统或插件绕过 CORS 的方法表明,它并不是完全万无一失的,如果有人真的想伪造标头,他们将能够做到。但当然,最终你可以让实现这一目标变得尽可能困难。但这需要实现和编写大量代码并进行大量检查才能实现。
你真的必须问自己目标和目标是什么。我认为这确实决定了你接下来的步骤。您可能会确定当前的设置足够好,无需进一步更改。您可能确定您正在尝试保护敏感数据不被发送到未经授权的来源,在这种情况下,CORS 可能不是一个可靠的解决方案(因为能够将该标头设置为任何内容)。或者您可能会确定您可能想要更多地锁定事物,并使用一些其他信号来更多地执行您的策略。
tldr您当然可以将Origin标头设置为您想要的任何内容,因此它不应该完全信任。如果您假设您的源标头应始终等于 API Gateway API 的域,则可以尝试使用该event.requestContext对象来获取有关 API Gateway 中 API 的更多信息,以获取有关请求的更多信息。您还可以查看Refer标题,看看是否可以将其与Origin标题进行比较。
更多信息:
Refer标头