Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为安全起见,获取JSONP请求来自的域名_Java_Javascript_Ajax_Jsonp_Xss - Fatal编程技术网

Java 为安全起见,获取JSONP请求来自的域名

Java 为安全起见,获取JSONP请求来自的域名,java,javascript,ajax,jsonp,xss,Java,Javascript,Ajax,Jsonp,Xss,我想让我的应用程序的用户能够在他们的网站上放置一些代码,并通过jsonp请求与我的服务器进行最少的交互。但是,我只希望远程请求能够来自我特别允许的远程站点。基本上,用户必须在我的应用程序中拥有一个帐户 为了安全起见,我的计划是: 要存储域,请求将在发出之前从中发出 允许在站点上放置代码 当服务器收到远程请求时,它将获取域名 并将其与数据库进行匹配 如果域匹配,则验证请求并返回 数据等。如果它不同,我将假定它是某种XSS攻击 排序并拒绝请求,将错误返回给远程服务器 如何获取请求来自的域?为了在我的

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

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

  • 要存储域,请求将在发出之前从中发出 允许在站点上放置代码
  • 当服务器收到远程请求时,它将获取域名 并将其与数据库进行匹配
  • 如果域匹配,则验证请求并返回 数据等。如果它不同,我将假定它是某种XSS攻击 排序并拒绝请求,将错误返回给远程服务器
  • 如何获取请求来自的域?为了在我的dev box上进行测试,我在不同的端口上设置了一个单独的静态网站

    Server domain: localhost:8090
    Remote domain: localhost:8095
    
    使用getRemoteHost似乎返回127.0.0.1。在现实世界中,这是远程域的ip吗?是否有可能从所述ip中找到人类可读的域名版本?存储和匹配ip可能不是一个好主意,因为我不知道尝试连接到我的服务的远程站点是否由动态ip提供服务

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

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

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

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

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

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

    然而。。。您提到这些远程站点上的用户将没有帐户。如果这意味着它们可供公众使用,那么任何人都可以获取这些远程站点中的一个,提取签名,然后自己使用它来做远程站点用户可以做的事情。这不是实现上的问题,而是架构上的问题:您的设计要求随机的web浏览器与您的服务交互,而根本没有办法阻止。使用共享秘密可以让你在一定程度上控制,但你无法阻止它


    在这一点上,我建议你退后一步考虑一下你真正想要解决的问题。这个接口做什么?这些远程站点上的浏览器是否需要直接与您连接?你想把谁挡在外面,为什么?如果他们绕过了您的检查,会发生什么?

    使用真正的安全性执行类似操作的唯一方法是使用安全连接,并为您的客户端提供某种API密钥。。。。正如@willglynn所指出的,由于JSONP的性质,这可能是一个棘手的问题。这是一个写得很好、考虑周全的答案。