如何安全地跨域将表单从静态 html 站点提交到服务器端后端?

How to securely cross domain submit a form from a static html site to a server side backend?

我想创建一系列静态 HTML 站点,这些站点将托管在 Amazon S3 上。

静态站点将具有表单。我的计划是 post/ajax 将表单数据提交到托管在不同域上的服务器端应用程序。服务器端应用程序会将数据存储在数据库中以供将来参考,并将提交的数据通过电子邮件发送给相关人员。

从表面上看这很简单,HTML 表单只需要 POST 数据到服务器端脚本,类似于 google forms/wufoo/formspree 等

我担心的是这对安全的影响。 post 会从静态站点跨域,这似乎使得 CSRF 难以在流行的 Web 框架中实现。我在 CSRF/CORS/Authentication 上阅读了很多博客 post,但我并不清楚。

通过研究 formspree.io 的源代码,他们似乎检查了引荐来源网址和来源 headers 以验证表单提交是否来自应有的网站以及已注册的网站。但是我知道这些可以被欺骗?

由于静态站点上的任何 javascript 代码都可以读取和逆向工程,API 样式验证似乎很困难...

或者我是不是想多了,如果我通过 SSL post 表单,验证表单数据服务器端,按照 formspree 检查 referer/origin headers 它应该是安全的够了吗?

TLDR;对于静态 HTML 站点 post 将表单数据发送到服务器端后端以存储在数据库中并通过电子邮件发送,我需要采取哪些安全步骤?

提前致谢!

在您的服务器上,您需要一些中间件来确保请求源是可信的。因此,如果您的静态 html 站点是 www.mysite.com,请确保服务器 www.mysite.com 允许访问您的 API。就身份验证而言,如果您不想让任何人访问您的 api,则需要某种类型的身份验证。基本流程如下所示:

用户发布登录数据,服务器进行身份验证,服务器生成令牌并发送回客户端作为响应,令牌存储在客户端并在发出任何请求时设置在 header 中。然后在你的路线上,你将需要一些中间件来检查请求中是否存在令牌header,如果是,则允许访问,否则,拒绝它。

希望这能解决一些问题。

最优解

您的情况下的最佳解决方案似乎是执行以下操作:

  1. 正在实施 Recaptcha。
  2. 首先将请求发送到您自己的脚本,验证验证码然后转发请求。
  3. 仅添加 Access-Control-Allow-Origin 您的 HTML 来源。 useful question

CSRF 保护

事实上,如果您只能访问客户端,则很难构建安全的应用程序。如果您要发布的服务没有 built-in CSRF 系统,如果您向 HTML 页面添加验证码并创建一个简单的 php,这将是一个很好的解决方案将接收表单字段、验证 recpatcha 并将表单字段提交到您想要的任何目的地的脚本。

通过令牌的 CSRF 保护也可以解决问题,实际上它是 clean-coding 解决方案,如果你最终首先提交给你自己的脚本,仍然,将它实现为静态 HTML 页。 (你需要通过 Javascript 或 php 脚本生成它,将它存储在你的 session 中,然后在你的后端脚本中验证它)但如果你是,我会推荐它能够编码。

  • 在这两种情况下,您都需要先提交到您自己的脚本,然后通过 CURL 转发请求。

正在验证 Headers

在您的后端脚本中,您可以验证引荐来源网址和来源,以确保请求不是来自您的 HTML 表单之外的其他来源。

总结

  1. recaptcha 将防止任何人对您的用户进行 CSRF 攻击。
  2. 如果攻击者试图找到源和引用检查的解决方法,他们可能会使用 CURL 之类的东西,recaptcha 也会阻止他们这样做。
  3. Access-Control-Allow-Origin 实施将阻止攻击者通过 javascript 向您的页面提交数据。
  4. 首先提交给你自己的脚本也会阻止任何人知道你提交这些数据的确切位置,这将使他们更难执行攻击。

虽然验证码不是一个非常 user-friendly 的解决方案,但如果您有能力编写 CSRF 保护系统,则需要通过 javascript 或发送 ajax 生成用户 session 唯一令牌的请求,然后您可以在其他 PHP 页面中验证该令牌,但无论如何您都需要实施验证码以防止垃圾邮件。