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

时间:2013-08-20 01:40:30

标签: javascript security iframe xss cross-site

我正在建立一个功能类似于Google Analytics的网站。我不是在做分析,但我试图提供一行javascript或一行iframe,它将为其他网站添加功能。

具体来说,嵌入内容将是一个按钮,它将弹出一个新窗口并允许用户执行某些操作。最终用户将完成并且窗口将关闭,此时按钮将更新为反映用户完成流程的新元素。

弹出窗口将从我的网站加载内容,但我的问题与嵌入的javascript(或iframe)行有关。这样做的最佳做法是什么? Google分析并优化使用javascript来修改主页。显然,iFrame也会起作用。

我遇到的安全问题是有人会从一个站点复制嵌入代码并将其放在另一个站点上。实现我的脚本/ iframe的每个页面/站点组合将具有该站点的开发人员将从我站点上的经过身份验证的帐户生成的唯一ID。然后我向他们提供适当的嵌入代码。

我的第一个想法是使用iframe从我的网站加载页面,并使用特定于页面/网站组合的网址参数。如果我走这条路线,有没有办法确定页面只是从嵌入特定域或网址前缀的iframe加载?用javascript可以实现类似的东西吗?

我阅读了this post,这非常有用,但我的用例有点不同,因为我实际上会弹出内容供用户进行交互。令人担忧的是,托管我的嵌入的网站的敌人会欺骗性地诱使他们自己的用户使用该小部件。这些用户会相信他们代表敌方网站与我的网站进行互动,但实际上是代表友好网站进行互动。

2 个答案:

答案 0 :(得分:11)

如果你想把它作为一个简单的,仅限客户端的小部件,那么简单的答案就是你不能像你描述的那样完成它。

为此想到的两个解决方案如下,第一个是折衷但简单,第二个涉及更多(对于您和您的小部件的用户)。

参考者检查

您可以验证referer HTTP header以检查域是否与特定站点ID的预期域匹配,但请记住,并非所有浏览器都会发送此域名(如果引用页面为HTTPS,则大多数浏览器都不会发送)并且某些浏览器隐私插件可以配置为隐藏它,在这种情况下,您的窗口小部件将无法工作,或者您需要额外的,笨重的用户体验步骤。

  1. 网站www.foo.com使用嵌入式脚本<script src="//example.com/widget.js?siteId=1234&pageId=456"></script>
  2. 嵌入您的小部件
  3. 您的窗口小部件使用服务器端代码动态生成.js文件(例如,对.js文件的请求可能遵循服务器上的重写规则以映射到PHP / ASPX)。
  4. 服务器端代码检查referer HTTP标头,看它是否与数据库中的预期值匹配。
  5. 在匹配时,小部件正常运行。
  6. 如果不匹配,或者引用者是空白/缺失,则窗口小部件仍会运行,但会有一个额外的步骤要求用户确认他们已从www.foo.com
  7. 确认他们已访问过窗口小部件
  8. 为了确保clickjacking的安全,您必须open the confirmation step in a popup window
  9. 服务器检查

    对于您的目的而言可能有点过度设计,并且对于希望嵌入您的窗口小部件的客户来说可能会变得过于复杂 - 您决定。

    1. 网站www.foo.com希望将您的小部件嵌入到用户收到的当前网页请求中。
    2. www.foo.com服务器发出API请求(传递密钥)到您托管的API,请求为ID 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页面刮取嵌入代码和参数。

答案 1 :(得分:0)

这里的回应非常透彻,提供了很多很棒的信息和想法。我通过在服务器端验证X-Frame-Options标头解决了这个问题,尽管在浏览器中对它们的支持是不完整的,并且可能是可欺骗的。