嵌入式iframe/javascript小部件的安全性

6
我正在构建一个与Google Analytics功能类似的网站。我不是在做分析,但我正在尝试提供一个单行JavaScript或单行iframe,以添加其他网站的功能。
具体来说,嵌入式内容将是一个按钮,将弹出一个新窗口,允许用户执行一些操作。最终,用户将完成并关闭窗口,此时按钮将更新为反映用户完成流程的新元素。
弹出窗口将从我的网站加载内容,但我的问题涉及嵌入式JavaScript(或iframe)。这样做的最佳实践方式是什么?Google Analytics和Optimizely使用JavaScript修改主机页面。显然,iFrame也可以工作。
我担心的安全问题是有人会从一个网站复制嵌入代码并将其放到另一个网站上。每个实现我的脚本/iframe的页面/站点组合都将有一个唯一的ID,该站点的开发人员将从我的网站的已验证帐户中生成该ID。然后,我向他们提供适当的嵌入代码。
我的第一反应是使用一个iframe,加载一个具有特定页面/站点组合的url参数的网站。如果我采用这种方式,是否有办法确定该页面仅从嵌入在特定域或url前缀的iframe中加载?类似的事情是否可以通过JavaScript实现?
我阅读了this post,它非常有帮助,但我的用例有点不同,因为我实际上要弹出内容供用户交互。问题是,托管我的嵌入式内容的网站的敌人会欺骗地引导他们自己的用户使用小部件。这些用户将相信他们代表敌对站点与我的站点进行交互,但实际上是代表友好站点进行交互。
2个回答

11

如果您想将其保持为一个简单的、仅在客户端使用的小部件,简单的答案是您无法完全按照您描述的那样做。

我能想到的两个解决方案分别如下,第一个是妥协但简单,第二个则需要更多的工作(对于您和您小部件的用户来说)。

Referer 检查

您可以验证 referer HTTP 头,检查域名是否与特定 Site ID 预期的一致,但请注意并非所有浏览器都会发送此头信息(如果引用页面是 HTTPS,则大多数浏览器不会发送),而且某些浏览器隐私插件可能配置为不发送它,这种情况下您的小部件将无法工作或者您需要在用户体验中增加额外的笨重步骤。

  1. 网站 www.foo.com 使用嵌入式脚本嵌入您的小部件,例如 <script src="//example.com/widget.js?siteId=1234&pageId=456"></script>
  2. 您的小部件使用服务器端代码动态生成 .js 文件(例如,请求 .js 文件可以在您的服务器上遵循重写规则以映射到 PHP / ASPX)。
  3. 服务器端代码检查 referer HTTP 头,以查看它是否与数据库中预期的值匹配。
  4. 当匹配时,小部件正常运行。
  5. 当不匹配或引用者为空/缺失时,小部件仍将运行,但会有一个额外的步骤要求用户确认他们是否从 www.foo.com 访问了该小部件。
  6. 为了使确认免受点击劫持攻击,您必须在弹出窗口中打开确认步骤

服务器检查

这可能有些过于复杂了,对于希望嵌入你的小部件的客户来说,存在变得太复杂的风险 - 由你决定。

  1. 网站www.foo.com想要为当前接收到的页面请求嵌入你的小部件。
  2. www.foo.com服务器向你托管的API发出API请求(传递一个密钥),请求Page ID 456的一次性密钥。
  3. 你的API验证密钥,生成一个安全的一次性密钥并返回一个值,同时记录请求在数据库中。
  4. www.foo.com嵌入脚本如下:<script src="//example.com/widget.js?siteId=1234&oneTimeKey=231231232132197"></script>
  5. 你的小部件使用服务器端代码动态生成js文件(例如.js可以遵循你服务器上的重写规则映射到PHP / ASPX)。
  6. 服务器端代码检查oneTimeKeysiteId组合是否有效,如果有效,就生成小部件代码并删除数据库记录。
  7. 如果用户重新加载页面,则将重复上述步骤,并生成新的一次性密钥。这将防止evil.com从页面抓取嵌入式代码和参数。

0

这里的回应非常详尽,提供了许多有用的信息和想法。我通过在服务器端验证X-Frame-Options头解决了这个问题,尽管浏览器对其支持不完整,可能会被欺骗。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接