我们,PHP 编码人员,并不总是在我们的代码中看到这个弱点。我们在识别用户(密码、会话等)方面做了大量工作,我们清理了代码以防止各种 SQL 注入。好的 !但是,如果一个完全识别的用户,他是合法的更新他自己的记录(比如他的 ID 24)只是将他的更新表单发送回你的应用程序,所有空字段和 ID = 23,然后 ID = 22,等等。一个人可以很容易在几分钟内清除所有记录(使用一点循环甚至更快:for(id=1, id < 10000, etc.)
所以,非常好的问题确实!
这是我的解决方案(当然不是最好的):
当一个识别的用户点击一个按钮来编辑他的记录时,我这样做:
- 我阅读了他的记录(SELECT)以获取数据。
- 我更新了该记录,其中包含两个临时信息:时间戳和随机字符串(35 个字符长的字符串,类似于 MD5,但随机创建)。
- 然后我向该用户发送包含所有数据的编辑表单,包括隐藏字段 {name="id" value="24"} 和另一个隐藏字段 {name"UpdatableOnlyBy" value="ks3kms36di7eur94k3n..."}
- 每当一个表单由 $_POST[] 返回以更新记录时,比如 #24,我接受只有在 {UpdatableOnlyBy} 字符串等于临时存储在该记录中的字符串并且时间戳不超过 20 分钟时才这样做. 然后,只有那时,我才执行 UPDATE(顺便将那个特殊的 {UpdatableOnlyBy} 字段设置回 Null)。
任何来自FOR ANOTHER ID的数据都不会导致任何 UPDATE,因为针对的记录没有相同的随机 {UpdatableOnlyBy} 字符串。
我留给你决定何时以及如何清理这两个字段,如果它们留下旧的 MD5 字符串和时间戳。就我而言,我在 0h25 有一个 cronjob,它清除了昨天和之前的所有这些字段。但在过去,我保留了这些数据,以查看有多少记录被拉出以更新留下“孤儿”(编辑从未回来的表单......)。在我的一个应用程序中,它不到 6%。