如何验证/保护/验证基于JavaScript的POST请求?

时间:2010-04-01 16:36:51

标签: javascript security authentication cross-domain jsonp

我正在帮助开发的产品基本上会像这样工作:

  • 网络发布商在其网站上创建一个新网页,其中包含来自我们服务器的<script>
  • 当访问者到达新页面时,<script>收集页面的文本内容并通过POST请求(跨域,使用<form>内部{ {1}})。
  • 我们的服务器处理文本内容并返回一个响应(通过JSONP),其中包含一个HTML片段,列出了Web上相关内容的链接。此响应被缓存并提供给后续访问者,直到我们收到另一个POST请求,其中包含来自同一URL的文本内容,此时我们重新生成“新鲜”响应。这些POST仅在我们的缓存TTL过期时发生,此时服务器表示并提示页面上的<iframe>再次收集和发布文本内容。

问题是这个系统本身似乎不安全。理论上,任何人都可以欺骗HTTP POST请求(包括引用标头,因此我们不能只检查它)将页面的内容发送到我们的服务器。这可能包括任何文本内容,然后我们将使用这些文本内容生成该页面的相关内容链接。

使这种安全的主要困难是我们的JavaScript是公开可见的。我们不能使用任何类型的私钥或其他神秘的标识符或模式,因为这不是秘密。

理想情况下,我们需要一种方法以某种方式验证对应于特定网页的POST请求是否可信。我们不能只是抓取网页并将内容与已发布的内容进行比较,因为让JavaScript提交内容的目的是它可能落后于登录系统。

有什么想法吗?我希望我已经很好地解释了这个问题。提前感谢任何建议。

10 个答案:

答案 0 :(得分:6)

这没有吸烟枪。但是,如果不存在大枪,那么主要的烦恼就可以了。黑客喜欢挑战,但他们更喜欢轻松的目标。太烦人了,他们放弃了。

谷歌和其他人用广告词有效地做到这一点。创建一个api令牌并让他们发送它。对使用您的脚本的站点进行“验证”过程,该脚本要求此脚本的注册人允许在使用脚本之前对其站点进行概要分析。然后,您可以收集有关服务器的所有信息,如果服务器配置文件与记录中的服务器配置文件不匹配,则可以请求。

获取有关浏览器和客户端的所有信息,并为其创建配置文件。如果有可能是浏览器欺骗,请删除请求。如果配置文件重复,但cookie已消失,请忽略输入。如果您在短时间内从令牌获得多个请求(即黑客尝试所固有的快速页面刷新),请忽略该请求。

然后更进一步,ping实际域以验证它是否存在并且是授权域。即使页面位于登录后面,域仍将响应。这本身不会阻止黑客,但它是服务器端,因此隐藏。

此外,您可以考虑分析页面的内容。如果一个专门用于厨房用具的网站开始发回成人约会的内容,请举起一面红旗。

最后,当一个错误的请求出现你被描述为错误的请求时,根据你知道的好的数据(该页面的24小时版本)发送JSONP对该页面的好请求等等。)。不要告诉黑客你知道他们在那里。好像一切都很好。他们需要花一点时间来解决这个问题!

这些想法都不能满足您的问题的确切需求,但希望它会激发您的一些阴险和创造性思维。

答案 1 :(得分:4)

这个怎么样? - 第三方网站包含的<script/>标记具有动态src属性。因此,它不是加载一些静态Javascript资源,而是来到您的服务器,生成一个唯一的密钥作为网站的标识符,并将其发送回JS响应中。您在用户会话或数据库中保存相同的密钥。此JS代码创建和提交的表单也将提交此关键参数。您的后端将拒绝任何与您的数据库/会话中没有匹配密钥的POST请求。

答案 2 :(得分:1)

基于每个域为人们提供密钥。

让人们在请求中包含[key string + request parameters]的值。 (哈希值应该在服务器上计算)

当他们向您发送请求时,您知道参数和密钥,可以验证其有效性。

答案 3 :(得分:1)

您所描述的系统的主要弱点是您“获得”了页面内容,为什么不去为自己获取页面内容?

  1. 网络发布商在其网站上创建一个新页面,其中包含来自服务器的脚本。
  2. 当访问者到达该新页面时,该脚本会向您的服务器发送获取请求。
  3. 您的服务器去获取页面内容(可能使用引荐来源标头来确定请求的来源)。
  4. 您的服务器处理文本内容并返回一个响应(通过JSONP),其中包含一个HTML片段,其中列出了Web上相关内容的链接。此响应被缓存并从服务器端缓存/代理
  5. 提供给后续访问者
  6. 当缓存版本的TTL过期时,代理会将请求转发到您的应用,整个周期将从第3步开始。
  7. 这可以阻止恶意内容被“馈送”到您的服务器,并允许您提供某种形式的API密钥,将请求和域或页面连接在一起(即api密钥123仅适用于mydomain.com上的引用 - 其他任何东西都是显然是欺骗)。由于缓存/代理,您的应用程序在某种程度上受到任何形式的DOS类型攻击的保护,因为每次缓存TTL到期时页面内容仅处理一次(现在您可以通过扩展TTL来处理增加的负载,直到您可以带来额外的处理能力)。现在你的客户端脚本非常小而简单 - 不再需要抓取内容并发布它 - 只需发送一个ajax请求并填充一些参数(api key / page)。

答案 4 :(得分:1)

首先,我会按照其他人的建议验证域名(也许是“服务器配置文件”),显然非常严格地验证POST的内容(我希望你们已经在做了)。 / p>

如果您将脚本文件的URL指向由服务器动态生成的内容,您还可以包含一个与POST一起发送的时间敏感会话密钥。这不会完全阻止任何人,但是如果你能够使会话足够快地到期,那么利用它会更加困难(如果我理解你的应用程序正确,会话应该只需要持续足够长的时间用户在加载页面后输入内容。)

输入后,我意识到它基本上是avlesh already suggested添加到期时的内容。

答案 5 :(得分:0)

如果您可以将服务器端代码添加到将数据推送到您的站点的站点,您可以使用MAC来至少防止未登录的用户发送任何内容。

如果只允许任何人使用该页面,那么我无法想到一种在不刮取网页的情况下确认数据的防水方式。你可以通过引用检查和诸如此类的方法使发送任意内容更加困难,但不是100%不可能。

答案 6 :(得分:0)

您可以哈希键特定每个客户端IP 地址,并使用帖子标题中的IP比较服务器上每个帖子的值。这方面的好处是,如果有人欺骗他们的IP 响应仍然发送到欺骗性IP 不是攻击者< / strong>即可。您可能已经知道这一点,但我也建议您在哈希中添加盐。

使用欺骗性IP无法进行正确的TCP握手,因此攻击者欺骗帖子未完成。

可能还有其他安全问题我不知道,但我认为这可能是一个选择

答案 7 :(得分:0)

网络发布者是否也可以在其服务器上放置代理页面?

然后通过代理加载脚本。然后,您可以通过多种方式控制两台服务器之间的连接,添加加密等等。

什么是登录系统?如何使用SSO解决方案并将脚本分开?

答案 8 :(得分:0)

你可以抓住网站,如果你得到一个代码200响应,包括你的脚本只是使用该刮。如果不是,您可以解决来自“客户端代理”的信息,那么问题就在于您无法抓住的网站。

为了提高这些情况下的安全性,您可以让多个用户发送该页面并过滤掉最少数量的响应中不存在的任何信息。这还具有过滤掉任何用户特定内容的额外好处。还要确保注册您要求执行代理工作的用户,并确认您只接收要求您执行此任务的用户的页面。您还可以尝试确保非常活跃的用户没有更高的机会完成这项工作,这将使得为此工作“捕鱼”变得更加困难。

答案 9 :(得分:-1)

怎么样:

站点A创建一个随机数(基本上是一个随机字符串),将其发送到您将其放入会话的站点B.然后,当站点A从站点发出POST请求时,它会发送nonce以及请求,并且只有当nonce与站点B的会话中的nonce匹配时才接受请求。