如何检查AJAX请求的真实性

Ale*_*ner 34 javascript language-agnostic security encryption ajax

我正在设计一个网站,用户可以尽快解决难题.JavaScript用于计算每个拼图,并在拼图完成时通过AJAX将毫秒数发送到服务器.如何确保服务器收到的时间不是由用户伪造的?

我不认为基于会话的真实性令牌(Rails中用于表单的那种)就足够了,因为我需要验证值的来源,而不仅仅是请求的合法性.

有没有办法以加密方式签署请求?我想不出黑客无法复制的任何东西.任何JavaScript,由于其暴露的客户端性质,都会受到篡改吗?我是否必须使用像Flash这样的编译器?(Yikes.)或者有什么方法可以隐藏密钥吗?或者其他我没想过的东西?

更新:为了澄清,我不想惩罚网络连接速度慢的人(网络速度应该被视为不一致),因此时间需要100%客户端(只有当我们知道用户可以看到时,计时器才会启动谜题).此外,涉及金钱,因此不能接受"信任用户"的数量.

Pet*_*ter 12

您无法以加密方式保证计时的安全性,因为客户端的浏览器无法进行安全计算.可以通过调整实际时序来绕过用于加密到服务器/从服务器加密的任何装置.

并且服务器上的时序也不起作用 - 如果您没有考虑到往返时间的延迟,那么具有较低延迟连接的用户将具有优势; 如果这样做,用户可以通过在那里添加额外延迟来阻止补偿阶段,然后再将其删除.

当然,你可以让用户很难对其进行修改,但无论如何,默默无闻的安全是一种不可持续的政策.

所以它归结为要么在某种程度上信任你的用户(大多数时候是一个合理的假设)和设计游戏,所以规避时间并不是微不足道的.

  • 我不能相信用户,因为涉及金钱(最快时间的奖品),一般来说,这听起来像是一个糟糕的政策.不仅有些人不值得信任,对守法用户(密码较弱)的描述也可能被劫持并被恶意使用. (2认同)

Anu*_*rag 10

这种方法显然是假设,并非不可战胜.所有计算都在客户端完成,服务器进行一些后台检查以确定请求是否可以伪造.像任何其他基于客户端的方法一样,这不是确定性的,但对于说谎的客户来说非常困难.

主要假设是长期HTTP连接对于传输数据要快得多,在某些情况下甚至可以忽略不计,具体取决于应用程序上下文.它用于大多数在线交易系统,因为股票价格可以在一秒内多次改变,这是向用户传输当前价格的最快方式.您可以在此处阅读有关HTTP Streaming或Comet的更多信息.

首先在客户端和服务器之间创建全双工 ajax连接.服务器有专用线路与客户端通信,客户端显然可以与服务器通信.服务器在此专用线路上将拼图和其他消息发送到客户端.客户端应该确认每个消息的接收连同其本地时间戳.

在拼图发送后,服务器上生成随机令牌(可能只是不同的整数),记录生成每个令牌的时间,并将其传递给客户端.客户端看到该消息,并且应该立即将该令牌与其本地接收时间一起中继.为了使客户端无法预测,请以随机间隔生成这些服务器令牌,例如介于ms 1nms 之间.

客户端将向服务器发送三种类型的消息:

PUZZLE_RECEIVED
TOKEN_RECEIVED
PUZZLE_COMPLETED
Run Code Online (Sandbox Code Playgroud)

以及服务器发送给客户端的两种消息:

PUZZLE_SENT
TOKEN_SENT
Run Code Online (Sandbox Code Playgroud)

可能是在消息大量时间变化的从客户端发送到服务器,但在其他方向上小得多(这是一个非常合理的假设,哎-我们必须从某个地方开始).

现在,当服务器收到它发送的消息的收据时,记录该消息中包含的客户端时间.由于令牌也在此消息中被中继,我们可以将其与服务器上的相应令牌进行匹配.在拼图结束时,客户端向PUZZLE_COMPLETED服务器发送带有本地时间的消息.完成拼图的时间是:

PUZZLE_COMPLETED.time - PUZZLE_RECEIVED.time
Run Code Online (Sandbox Code Playgroud)

然后通过计算每条消息的发送时间与接收时间的时间差来进行双重检查.

PUZZLE_RECEIVED.time - PUZZLE_SENT.time
TOKEN_RECEIVED.time - TOKEN_SENT.time
Run Code Online (Sandbox Code Playgroud)

这些时间的高度差异意味着响应可能是伪造的.除了简单的方差外,您还可以对此数据进行大量统计分析,以寻找奇怪的模式.


ZoF*_*reX 8

甚至编译的应用程序也可以伪造.如果用户在计时中途更改了系统时钟,则应用程序将向服务器报告错误的时间.获得精确上限的唯一方法是在给出谜题时在服务器上开始计时,并在提供答案时停止计时.

正如其他人所指出的那样,通过使拼图的负荷尽可能小,可以最大限度地减少连接速度慢的影响.首先加载整个页面和"游戏引擎",然后使用异步请求加载拼图本身(应该是少量数据)以尽可能地平衡游戏场.

不幸的是,你不能做延迟补偿,因为这可能会被篡改.然而,在一个没有被用于其他任何东西的连接上,这样一个请求的延迟会因人类解决一个谜题的时间而大大黯然失色,我认为这不会是一件大事.

(推理:200毫秒被认为是非常糟糕的滞后,这是人类平均反应时间.人类完成的最短可能的"难题"是视觉反应速度测试,在这种情况下,坏的延迟将在他们的100%标记上因此,作为时间解决方案,这是2-OPT.任何更复杂的难题都会受到滞后影响.)

我还会在页面上放置一个标语,说明在播放最佳速度时不要使用互联网连接,可能链接到速度/延迟测试仪.