【问题标题】:Bypassing the Same Origin Policy for authenticated XmlHttpRequests绕过经过身份验证的 XmlHttpRequests 的同源策略
【发布时间】:2011-12-23 20:46:11
【问题描述】:

我在foo.com 上有一个网站,服务于PageA

PageA 中有一些 JQuery,它通过 XmlHttpRequest 从位于 bar.com 的 CouchDb 实例请求一些 JSON 数据。

据我了解,同源策略可以防止这种情况发生,但 JSONP 的使用应该会绕过这个限制(我相信,CORS 最终会涵盖这个用例。)

foo.com 后面的服务器与bar.com 的数据库建立了可信连接。

是否可以让用户使用其 OAuth 凭据(例如 Twitter 登录)通过 foo.com 进行身份验证,然后通过身份验证以使用 bar.com? (我认为不是因为身份验证 cookie 只能由 foo.com 读取。)

鉴于此,我是否可以使用任何可用的 CouchDB 身份验证机制(OAuth、cookie 和 Basic)对用户进行身份验证,以便在 bar.comfoo.com 使用 CouchDB ?

编辑: 例如,我是否可以从 foo.com(通过其受信任的链接检索)返回 bar.com 的用户凭据,然后在 XmlHttpRequest HTTP 标头中为基本设置客户端使用bar.com 进行身份验证。当然,所有这些都是通过 TLS 完成的(……或者这是一场安全噩梦?)

【问题讨论】:

    标签: authentication oauth couchdb same-origin-policy


    【解决方案1】:

    从我的 POV 来看,即使 JSONP 也是一种安全风险——所以我不会走这条路……

    为了实现您的要求,我看到了两个选项(如果需要,都可以使用 SSL!):

    • 编写一个自定义的 webservice/REST/SOAP/whatever 在foo.com 上运行并代表您与bar.com 进行交互以供经过身份验证的客户端

    • 使用在 foo.com 上运行并映射 bar.com 的“通用 http 代理”,使您的应用/页面的工作方式就像 CouchDB 在 bar.com 上运行一样用于经过身份验证的客户端

    【讨论】:

      【解决方案2】:

      据我了解,您希望使用 foo.com 的 JSONP 在 bar.com 上发出请求,同时希望 bar.com 能够知道此请求是否已通过 foo.com 的身份验证。

      这就像登录 foo.com 并允许将真实性转移到 bar.com。

      假设 XMLHttpRequest 可以记住其余请求的 cookie 中的会话 id,那么使用一次性密码(实际上是一个随机字符串,我们可以称之为令牌)调用 bar.com 怎么样从 foo.com 登录后生成的页面如下图所示:

      login request -> foo.com -> XHR(bar.com, OTP) -> bar.com
      cookie updated with an active session id <- bar.com
      XHR(bar.com, CounchDB) -> bar.com successfully
      

      因此,如果 foo.com 和 bar.com 可以私下通信(并且安全!),foo.com 可以生成一个 OTP 并将其传递给 bar.com,以便 bar.com 知道只有有效用户才能知道它并且因此可以将会话 ID 视为经过身份验证。

      替代课程:

      1. 如果 XMLHttpRequest 对 bar.com 使用的 cookie 不会在请求中持续存在,则必须在每个请求中传输相同的 OTP。
      2. bar.com 必须提供一项服务来监控来自 foo.com 的新添加 OTP 的身份验证授权。它应该有一些超时机制来使旧令牌失效。
      3. bar.com 可能还需要提供身份验证删除服务,以防止使用公共机器时的风险。

      【讨论】:

        【解决方案3】:

        我在 xhr 中遇到了关于同源策略的相同问题。我有一个网站,我想使用来自运行 CouchDB 的不同服务器的 JSON 数据填充自动完成内容。

        有两种方式:

        1. JSONP - 这很好用
        2. 通过主 Web 服务器代理 CouchDB - 从客户端 b/c 的角度来看,这非常有效,所有内容都在同一主机上。它还使 SSL 成为可能。

        就从 CouchDB 和另一个应用服务器共享登录会话而言,如果不求助于基本的 HTTP 身份验证,我不知道该怎么做,这并不是那么安全。让应用服务器充当中间人 b/t 客户端和 CouchDB 可能会更好。

        应用服务器中间人的另一个好处是单个 CouchDB 数据库可以包含多个用户的文档。相比之下,如果客户端直接访问 CouchDB,您可能需要通过过滤复制为每个用户创建一个单独的数据库,这样一个用户就无法查看另一个用户的文档。

        【讨论】:

          【解决方案4】:

          您可以从 facebook 身份验证服务器流程中获得灵感,将客户端替换为您的客户端,将服务器替换为 foo.com,将 facebook 替换为 bar.com。看http://developers.facebook.com/docs/authentication。这样,客户端应该已经过身份验证以使用来自 bar.com 的数据(当然,在从 bar.com 加载的脚本中,但您可以将数据从 foo.com 传递给回调,除非我弄错了)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-03-17
            • 2012-12-30
            • 1970-01-01
            • 2011-08-13
            • 2014-12-20
            • 1970-01-01
            • 1970-01-01
            • 2012-04-30
            相关资源
            最近更新 更多