如何保护/加密JavaScript POST请求

4
我有一个游戏,其中我的JavaScript通过POST调用PHP脚本来更改数据库中的值。我该如何防止某人重复复制请求并赋予自己数十亿点?
目前,我通过 sha1() 传递密码,并检查PHP端是否存在,但这不会阻止某人重复请求。
我不能使用时间戳,因为JS POST请求和PHP脚本运行之间会有时间间隔。
编辑: 我的PHP脚本不会递增数据库值(points=points+10),它接受传递给它的值并更新字段(points=300)。 在游戏中每次“交互”(导致积分上升的每次交互)中,我会更新几个表格。其中一个表格仅允许用户对任何图像投票一次。如果我首先进行此更新,如果用户试图重复此请求,则结果将返回错误,我可以终止PHP脚本。
这样的安全措施是否足够?我还需要担心防止重复请求吗?

1
这里有一个类似的问题:https://dev59.com/i3E85IYBdhLWcg3w64IA ,答案基本上是不可能的。 - longstaff
5个回答

2

听起来现在这个逻辑大部分都留在客户端,因此您无法阻止某人多次发送“score.php?score=1000”的请求。

在服务器端添加逻辑,检查特定请求可以执行的频率,或者更好的是,在服务器端完全执行游戏逻辑(因此用户不必提交自己的分数,而只需请求执行某个游戏操作,最终会产生一个分数,然后可以将其添加到用户中)。


  1. 那是GET请求,不是POST请求,但我明白你的意思。
  2. 我不想在最后执行这个动作,因为如果用户表现不佳,他们可以重新加载页面,那一轮就会被忘记。
- Adam Lynch
我相信你知道@Adam,但无论是GET还是POST都可以轻松地由客户端完成。 - Kenny Cason

1
如果您有某种形式的会话标识符,可以增加请求已被执行的次数。但这并不是绝对可靠的,因为清除会话 cookie 将允许再次发出该请求。
您需要某种形式的登录来防止某人清除他们的 cookie,或者甚至是一个循环的 cURL 脚本。
编辑:
作为一种临时措施,您可以添加一种 CSRF 保护形式,每个请求都需要应用一次性使用的哈希才能使其有效。

CSRF一次性哈希会很好,但PHP端如何知道要对其进行检查?时间戳行不通。 - Adam Lynch
2
它将保存在会话中 - 每个请求都会返回一个新的,可以在下一个请求中使用。 - ThiefMaster

0

你也可以从post中传递一个标记,当你真正想要在数据库中更新该值时,可以将其设置为任何值,否则将其设置为0。在更新时检查标志的值并相应地进行更新。


当你说更新它时,我假设你的意思是这个值在每个请求中都会不同?这个值可能是什么?PHP如何预先知道它将是什么? - Adam Lynch
不,我的意思是每当您将值存储在数据库中时,都会在某个地方进行计算,然后在数据库中更新它,因此您可以为该值设置标志,例如1,并在发布后检查其值。然后再次将其存储在数据库中并将该标志设置为0。因此,通过这种方式,在更新数据库后,标志将再次变为0,不会输入重复值。 - Astha
我的计算是在JS中完成的,而SQL更新是在PHP中完成的。难道有人不可以使用Firebug来复制/攻击吗?或者如果我将计算移动到PHP脚本中,那么他们就可以轻松地复制请求了。 - Adam Lynch
如果这只是一个重复的条目而不是增量条目,您可以在 PHP 页面上进行检查。如果相同的数据已经存在,则不要更新它,否则执行更新操作。 - Astha

0

鉴于客户端可以轻松地执行GET或POST,如果您只是向服务器发送原始分数,则永远不会有好结果。我从未编写过在客户端上发生如此多逻辑的游戏。客户端应该只向服务器发送命令,而服务器决定是否为有效事务/状��。更多或更少,服务器知道客户端的状态,而客户端只反映那个状态。这可能是确保客户端操作合法的唯一真正方法。


-3

使用 captcha Wiki CAPTCHAreCAPTCHA

此外,使用Session将用户的重复请求次数写入服务器,并在每个成功请求时递增它,

然后通过会话存储数据阻止用户访问您的PHP脚本。 PHP SESSIONS


每次数据库交互都出现验证码?那会破坏游戏体验。关于“重复请求的数量”,我不是完全确定你的意思,能否解释一下? - Adam Lynch
创建一个 $SESSION['number_of_request'],然后将 $SESSION['number_of_request'] 的默认值设置为 ZERO,并在每个成功的请求中递增它。如果您认为用户经常向服务器发送许多请求,则可以使用 PHP 的 if 语句阻止他访问您的脚本,还可以在每隔 x 分钟或小时后清除会话 :) - Pawan Choudhary
但是用户可以清除会话吗?这将允许他们进行 number_of_allowed_interactions-1 个欺骗性交互。 - Adam Lynch
用户无法控制会话,但在使用 cookies 的情况下可以。 - Pawan Choudhary
那么我需要通过调用 PHP 脚本来分配会话变量,对吧?好的,他们可以复制那个脚本,并进行实际请求以获取积分。 - Adam Lynch
如果您有一个数据库,那么请为每个用户分配一个唯一的“id”,添加一个名为“number_of_request”的列,然后将会话数据写入其中。顺便说一下,用户不能自己复制会话,但是他们可以使用另一个浏览器来欺骗我们的系统,但是通过为每个用户分配一个唯一的数字“id”,您也可以防止这种情况发生。 - Pawan Choudhary

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接