WEB3钱包如何为支付网关提供商实现 USDC 支付
Lua CORS 指南: 它是什么以及如何启用它
跨站点请求伪造 ( CSRF ) 是一种严重的 Web 攻击,每个开发人员都需要考虑。黑客利用它对 Web 应用程序进行攻击,窃取有价值的用户信息。ING Direct、Netflix和YouTube等主要网站都曾发现破坏性攻击。最好的防御方法是将 Web 应用程序限制在单个域中,但这并不总是明智或可行的。您需要一种方法来确保跨域请求的安全。这就是跨源资源共享 ( CORS ) 的作用所在。它是一种允许应用程序使用多个 Web 和 API 服务器的工具。
Lua 是一种流行的脚本语言,用途广泛,包括 Web 应用程序。因此,它也容易受到 CSRF 攻击。您需要设置 Lua CORS 吗?
这篇文章将介绍什么是 CORS、它避免的问题以及如何使用 Lua 应用程序实现 CORS。
CORS 简介
在深入研究 Lua CORS 之前,我们先简单了解一下什么是 CORS。
跨域资源共享是一种安全机制,它根据应用的来源(浏览器加载应用的域)定义应用可以请求的内容。所有现代 Web 浏览器都默认实现该机制,以保护用户免受CSRF和类似攻击。因此,如果您希望应用访问多个域,则需要 COR。好消息是,大多数 Web 基础设施都会为您处理它。
CORS 错误实战
CORS使用 HTTP 标头来确定谁可以与您的特定目标进行交互。“开箱即用”,CORS 会阻止来自不同来源的所有请求。想象一下,一个 Web 应用程序的 HTML 由位于https://example.com:443 的 Web 服务器提供。此外,它还使用位于https://example.com:8083的 API 服务器。当应用程序在 Web、桌面和移动版本之间共享 API 时,这种情况很常见。如果不进行任何额外配置,CORS 会阻止对 API 服务器的调用。因此,Web 应用程序将失败。
如果您打开浏览器的 Web 控制台,您将看到如下错误:
Access to XMLHttpRequest at 'https://example.com:8083' from origin 'https://example.com' has been blocked by CORS policy
这里发生了什么?应用程序向 example.com 的服务器发出了两个请求。为什么浏览器拒绝了第二个请求?
CORS 定义了包含三个不同部分的来源:
- 协议 – 在本例中两者都是 HTTPS
- 域名 – 均为 example.com
- 端口 – 一个是 443,另一个是 8083
根据 CORS 规则,不同的端口意味着不同的来源。因此,它阻止了请求。由于没有覆盖 CORS 策略,现代 Web 浏览器默认采用同源策略;代码只能从浏览器检索资源的来源请求资源。
如何让这样的应用程序与 CORS 协同工作?
CORS 何时起作用
现在我们了解了没有 CORS 会发生什么,让我们来讨论一下当启用 CORS 的浏览器允许应用程序发出跨源请求时会发生什么。上游应用程序需要做什么才能实现这一点?
一旦脚本向其他来源发出请求,CORS 工作流就会启动。浏览器通过向第一个来源发出“预检”请求来启动该过程。该请求使用 HTTP OPTIONS 方法并包含有关该请求的详细信息。
服务器验证请求并响应一组可接受的请求。此响应详细说明了允许的内容。它包含有关允许的内容的信息:
- 脚本可以发出请求的来源。
- 脚本可以与来源一起使用的请求方法。
- 脚本可以发送到原点的自定义标头。
- 脚本可以发送给源端的身份验证信息。
如果您想了解有关 CORS 背后的更多细节,包括如何不设置它以及典型的攻击是什么样的,请阅读我们详细的 CORS 指南。
Lua CORS
Lua 是一种流行的脚本语言,具有无数不同环境的绑定和实现。在某些情况下,使用它时需要牢记 CORS。
当您考虑到 CSRF 攻击带来的风险以及像 LUA 这样的可以访问几乎所有 C 运行时库的语言的强大功能时,您可能想要编写自己的 CORS 库。
不。
CORS 是 HTTP 协议的一部分,您不想将其实现与应用程序代码混合在一起。您也不想重新发明轮子,尤其是当已经有经过验证的轮子可供您使用时。
OpenResty
OpenResty是基于Nginx和 Lua 的应用服务器。它将 Nginx 核心与为 Lua 定制的即时 (Jit) 编译器相结合。因此,它是一个在 Nginx 内部运行扩展的平台,利用了其事件模型。由于 Lua 可以直接调用 C 扩展,因此您可以使用 OpenResty 运行几乎任何东西。您还可以使用Lapis(一个在 OpenResty 内部运行的 Web 框架)开发 Web 应用。
如果您认为一款几乎无所不能的应用程序听起来像是需要特别安全保护的应用程序,那么您的想法是对的。应用服务器几乎不可避免地会受到 CSRF 攻击,因此您需要保护自己免受此类攻击。
OpenResty 项目有一个名为lua-resty-cors 的CORS 库,它集成到平台中并添加了允许的来源、方法、标头和其他关键 CORS 设置的配置选项。它是Nginx 类似过滤器的反向移植。
如果您在网上阅读一些论坛帖子和其他消息,您会看到建议将允许的域或来源设置为*, 以便您的应用程序可以正常工作。不要这样做。如果这样做有效,您的应用程序就会受到攻击。很有可能,它无论如何都无法正常工作。
如果 example.com 应用程序在 OpenResty 上运行,我们会像这样配置平台。
http {
init_by_lua_block {
local cors = require('lib.resty.cors');
cors.allow_host([==[.*\.example\.com]==])
cors.allow_method('GET')
cors.allow_method('POST')
cors.allow_method('PUT')
cors.allow_method('DELETE')
cors.max_age(7200)
cors.allow_credentials(false)
}
header_filter_by_lua_block {
local cors = require('lib.resty.cors');
cors.run()
}
}
此配置允许代码从 example.com 域中的任何主机(包括 api.example.com)发出请求。它明确允许 GET、PUT、POST 和 DELETE 动词,但不允许脚本将凭据发送到跨源目标。
Nginx
如果您只想运行一些简单的脚本或编写自己的 Web 代码,Nginx 的lua-nginx-module可以运行 Lua 脚本来响应事件。
Nginx 有上面的 ngx_http_cors_filter,它将为您实现 CORS 消息传递。其配置与上面的 OpenResty fork 相同。这里有详细的配置说明,其中包括如何不在顶部配置它 的示例。
阿帕奇
Apache 的mod_lua类似于 Nginx 的 Lua 插件。你可以使用它来编写在服务器内部运行的 Lua 脚本。
再次,您需要为 CORS 配置 Web 服务器并让它为您实现 HTTP 消息传递。
如果您快速搜索“apache cors”,您会看到类似的建议。
<Directory /var/www/html>
Order Allow,Deny
Allow from all
AllowOverride all
Header set Access-Control-Allow-Origin "*"
</Directory>
这是糟糕的建议。第 5 行在服务器上打开了一个很大的安全漏洞,漏洞大到某些浏览器甚至可能会忽略并拒绝跨源请求。
不要向任何请求开放服务器,而是使用正则表达式:
<Directory /var/www/html>
Order Allow,Deny
Allow from all
AllowOverride all
SetEnvIf Origin "^http(s)?://(.+\.)?example\.com$" AccessControlAllowOrigin=$0
Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
</Directory>
这是一个更安全的设计,并模拟了上面的 Nginx 配置。