【问题标题】:Checking whether an ID was changed on client side before database update在数据库更新之前检查客户端是否更改了 ID
【发布时间】:2014-08-31 04:14:35
【问题描述】:

考虑以下示例: HTML 页面:

<input type="text" name="update_12" />

名称为“update_12”和新文本为:“Some another data”的输入框通过表单发送 到服务器端 PHP 脚本(比如 process.php)

数据库格式:

=====================
message_ID  Message
=====================
12         Some data
13         Another data

如果 PHP 脚本将输入名称分解为:

foreach ($_POST as $key => $value) {
    if(strstr($key, "update_")){
        $required_id = explode('_',$key)[1];
        $query = "UPDATE <db_name> SET `Message`='".$_POST[$key]."' WHERE `message_id`='".$required_id."'";
    }
}

这会使用 message_ID 的新消息更新数据库:12

我是 PHP 新手,正在探索 MySQL 中的基本数据存储、更新、检索和删除。

由于客户端可以更改输入字段的名称:“名称”并发送另一个值进行更新。 例如:如果客户端打开firebug,将输入框的“name”字段更改为“update_13”,他的操作将覆盖另一个用户的Message。

我尝试通过在 facebook 中删除状态来对此进行研究。 从对 POST 删除数据的初步观察,我可以看到一些重要的参数被发送为删除:

impression_id=456ab622
profile_id=100005552221116
__user=100005552221116
story_fbid=540912345678911

对于帖子删除,关联的 ID 类似于:story_fbid。 当我将其更改为可能是:540912345678912(最后一位已更改) 并单击删除,fb 需要一段时间并以错误消息响应:无法完成此操作。此错误消息在发送删除的 POST 请求后出现(修改 story_fbid)。 POST 请求的响应包含显示在模式窗口中的错误消息。

我可以想到一种方法,其中 ID 及其哈希 (MD5/SHA1/SHA2) 存储在 DB 中,并在收到 id 后,获取它的哈希,如果匹配,则更新 DB 中的该行。 但是,(在我们的例子中)哈希值 13 可能会匹配任何其他行并因此执行更新操作。

您能否提出任何其他安全的方法来验证客户没有更改值?

here 提出的问题的答案正是我想要的。但是,该讨论中没有合适的解决方案/方法。

【问题讨论】:

    标签: php mysql server-side-validation


    【解决方案1】:

    您可以使用自己的函数或内置的 php 函数 uniqid() 创建唯一的生成 ID(ID1)。启动用户会话并在会话中存储 ID1 和消息 ID(ID2),如下所示。

    session_start();
    $ID1 = uniqid();
    // store session data
    $_SESSION['ID1']=$ID1;
    $_SESSION['ID2']=$ID2;
    

    假设生成的 ID 是“145f214”。 您表单中的输入将如下所示

    &lt;input type="text" name="update_145f214 /&gt;

    当表单提交时,您只需在输入元素中获取 ID1 并检查:

    1. 如果会话中的 ID1 具有相同的值
    2. 如果是,请使用会话中存储的 ID2 的值进行 sql 查询
    3. 如果没有,则向用户显示错误消息

    这是一个非常基本的解决方案,但从那里你肯定会改进。

    如果您有很多字段并且使用成对的数据,那么您需要在会话中保存这些对和另一个。

    假设您有 10 个字段的数据如下:[12a:1][12b:2][12c:3]

    您可以将字段的顺序和相应的数据保存到会话变量中。

    $_SESSION['field1'] = [12a:1];
    

    $_SESSION['field2'] = [12ba:2];

    可能也是这个

    $_SESSION['fieldCount'] = 10;
    

    确保您知道自己生成了多少个字段

    您可以从那里首先检查提交的字段数是否与您生成的字段数相同。然后,您通过与会话变量中的数据进行比较来检查所有字段是否具有您分配给它的对(这也有助于检查顺序是否已更改)。

    我回到这个是因为我有一个类似的案例并实施了上述解决方案。

    如果你愿意,我可以给你更多细节

    【讨论】:

    • 需要一些澄清:我知道 session_start() 会生成一个 SID。当您说唯一生成的 ID 时,您指的是同一个 SID 吗? DB ID 是否与问题示例中给出的 Message_ID 相同?问题中提到的表单 ID 是什么? (那是输入的名称字段吗?
    • 是的,这看起来像是一种基本方法,适用于少量输入/文本区域。但是,如果有 10 个输入,使用 UUID 方法需要我们跟踪 UUID:ID 对,并且在这种情况下无法检查 HTML 输入“名称”字段中哪个 UUID 被编辑/更改。示例:如果 [UUID:ID] 对是 [12a:1][12b:2][12c:3] 等等,现在如果用户将 message_12a 更改为 message_12b,他将被允许对行进行错误更新使用主键“2”。如果您可以建议任何其他方法,将有助于我对此进行更多探索。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    • 2017-11-26
    • 2016-10-03
    • 2016-01-28
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    相关资源
    最近更新 更多