获取JSONP请求来自安全性的域名

时间:2012-09-22 15:10:20

标签: java javascript ajax jsonp xss

我想允许我的应用程序的用户能够在他们的网站上放置一些代码,并通过jsonp请求与我的服务器进行最低限度的交互。但是,我只希望远程请求能够来自我明确允许的远程站点。基本上,用户必须拥有我的应用程序帐户。

为了安全起见,我的计划是:

  1. 要存储域,请求将在它们之前发出 允许将代码放在网站上。
  2. 当服务器收到远程请求时,它会获取域名 来自请求并将其与数据库进行匹配。
  3. 如果域匹配,则验证请求并返回 数据等。如果它不同我会假设它的某些XSS攻击 排序并拒绝请求,将错误返回给远程。
  4. 如何获取请求来自的域?为了在我的开发箱上进行测试,我设置了一个在不同端口上运行的独立静态网站

    Server domain: localhost:8090
    Remote domain: localhost:8095
    

    使用getRemoteHost似乎返回127.0.0.1。在现实世界的情况下,这将是远程域的IP,然后可以从所述IP中找到人类可读的域名版本吗?存储和匹配ip可能不是一个好主意,因为我不知道试图连接到我的服务的远程站点是否正在从动态IP提供服务...

    也许我在这里采取了错误的做法,所以如果我错了请纠正我。无法向远程站点的用户请求用户名和密码,因为他们没有实际帐户。

    也许更好的方法是在数据库中存储某种加密的令牌而不是域,当我向用户提供放置在其站点上的代码片段时,它可能包含一个包含加密的隐藏输入每个请求传递的此令牌的版本?但是,在这种情况下,是否有人能够通过查看页面源来复制隐藏元素并对服务器具有相同的访问权限?

1 个答案:

答案 0 :(得分:3)

一方面,你说“我只希望远程请求能够来自我特别允许的远程站点”,但使用JSONP意味着你不会看到来自远程站点的请求 - 你会看到来自访问远程站点的浏览器的请求。这种区别很微妙但很重要,因为它严重限制了你的选择。

如果您想知道哪个站点发起了JSONP请求,您可以检查Referer标头。除了......你不能依赖它被设置,尤其是跨HTTP / HTTPS转换。然后你可能会想“嘿,我会使用CORS”,但当然,任何人都可以使用他们想要的任何标题创建请求。我可以编写一个声称是您的远程站点之一的HTTP客户端,并使用他们的凭据访问您的界面 - 因此,如果标题是您限制访问的唯一方式,请知道它很容易被击败。

Referer标题上面的下一步是发出令牌并使用它们进行识别。但是,正如您所指出的,远程站点必须将此权限提供给浏览器,以便浏览器创建请求。所以,有人可以复制它并在任何地方使用它。回到同一个问题。

您可以做的下一件事是发放令牌(用于识别)以及共享密钥(用于授权)。然后,您可以要求远程站点使用共享密钥来签署请求 - 说“是的,它实际上是我,远程站点”。通过这种方式,远程站点为用户的浏览器提供了签名,但不是秘密本身。您需要确保您签署的内容足以验证远程站点的意图(即站点希望用户的浏览器执行的任何操作),并且它应包含防止重放攻击的时间戳。这需要远程站点进行一些服务器端计算,但会阻止用户采取除远程站点明确允许的操作之外的任何操作。

但是......你提到这些远程站点上的用户没有帐户。如果这意味着它们可供公众使用,那么任何人都可以获取其中一个远程站点,提取签名,并自己使用它来执行远程站点用户可以执行的操作。这不是实现的问题,它是架构的一个问题:您的设计要求随机Web浏览器与您的服务进行交互,而且根本无法阻止man-in-the-middle。使用共享秘密可以让你有一定程度的控制,但是你无法阻止它。

此时,我建议您退后一步,考虑一下您实际要解决的问题。这个界面有什么作用?这些远程站点上的浏览器是否需要直接与您连接?你想要阻止谁,为什么?如果他们绕过你的支票会怎么样?