【问题标题】:Code for Updating MySQLI PHP更新 MySQLI PHP 的代码
【发布时间】:2013-12-09 10:36:57
【问题描述】:

有些人一直告诉我,我在 mysqli 查询中更新数据的代码非常不安全。实际上,这个网站上有几个人。所以我想知道他们说什么可以保护我下面的代码,所以在更新我的数据库时它是安全的。我想知道如何保护我的 mysqli 查询。

好的,在我的数据库条目代码中,这就是我所做的。首先让我说我总是通过 POST 方法发送以避免浏览器 url 复杂化。

当我得到 POST 数据时,这是我的代码。

$ID = 1;
$DATA = htmlentities(addslashes($_POST['data']));
$FIELD = "lifename";
$DBQUERY = "UPDATE `lifetable` SET `$FIELD` = '$DATA' WHERE `id` = $ID";
$DBRESULT = $MYSQLI->query($DBQUERY);

我目前在我的本地网站上使用它。

如果我已经转义了所有引号、所有斜杠、所有 & 符号(从 javascript 到 ajax)和所有分号,这怎么会不安全?这怎么可能?

那么你能告诉我在向我的数据库中添加信息时应该改变什么吗?

谢谢

PS ...我正在使用mysqli并将继续使用它。谢谢

【问题讨论】:

  • 尝试使用 PDO 语句进行 DB 查询。然后你就在保存端了。 php.net/manual/en/intro.pdo.php
  • forums.mysql.com/read.php?52,227585,227585 请阅读这篇文章你可能会在使用 pdo 之后得到一个好主意,因为它很好地抽象了数据库查询而不是供应商特定的函数 mysql 或 mysqli
  • 有一种方法可以保护 mysqli,所以你甚至从来没有接近回答我的问题,我的标签特别提到了 mysqli。我在问如何使我的 mysqli 语句更安全。
  • 复制标签下投票最多的问题,stackoverflow.com/questions/60174/…

标签: php mysql database mysqli


【解决方案1】:

一些人建议我从 mysqli 更改为 pdo,但我不愿意完全 100% 更改从数据库访问数据的方式。有人在preparebind_param 之前发布了另一个链接,这就是我要使用的。所以谢谢你。

现在这是我的代码,绑定参数应该是这样,每个参数只用于我的查询的一部分,不能用于其他任何东西,根本没有其他任何东西。

    $DBQUERY = "UPDATE `lifetable` SET `lifename` = ? WHERE `id` = ?"; // EACH ? IS A PART OF bind_param BELOW IN ORDER AFTER TYPE.

    $STMT = $MYSQLI->prepare($DBQUERY);
    $STMT->bind_param('si', $DATA, $ID); // THIS MAKES SURE THAT THE VARIABLES ARE ONLY USED FOR THERE PLACE HERE AND NOTHING ELSE. ? in order.

    $DATA = htmlentities($_POST['data']); // I STILL USE MY CODE HERE TO REMOVED ANY OTEHR CHARACTERS, JUST INCASE. AND BEFORE IT GETS HERE, IT USES encodeURIComponent TO OUTPUT FROM AJAX.
    $ID = $COLUMN[1];

    $STMT->execute();
    $STMT->close();

我的代码以前有效,现在有效,只是更安全,至少有人告诉我。

【讨论】:

    【解决方案2】:

    像这样使用 PDO 类:

    $db = new PDO('mysql:host=localhost;dbname=<SOMEDB>', '<USERNAME>', 'PASSWORD');
    $query = $db->prepare('UPDATE `lifetable` SET :FIELD = :DATA WHERE `id` = :ID');
    $query->execute(array(
      ':FIELD' => $field,
      ':DATA' => $data,
      ':ID' => $id
    ));
    $query->commit();
    

    欲了解更多信息Are there good tutorials on how to use PDO?

    【讨论】:

    • 对不起,但我在谈论使用 mysqli,正如我在标签中所说的那样。不过谢谢
    • 这只是一个小例子,应该告诉你正确的方向。
    • 哦 - 我只是错过了这个小 i - 很抱歉。
    • 我对使用 mysqli 感到很自在,此时不值得学习一种全新的方式来使用 mysql 数据库。不过谢谢
    • 我会从中得到一件事,那就是mysqli_prepare 并将它与bind_... 一起使用。感谢您的帮助!
    【解决方案3】:

    我认为您的安全性在于 SQL 注入,我知道使查询安全的最佳方法是在 var 上使用 mysql_real_escape_string。这里的例子取自 php.net

    $mysqli = new mysqli("localhost", "my_user", "my_password", "world");
    $city = $mysqli->real_escape_string($city);
    $mysqli->query("INSERT into myCity (Name) VALUES ('$city')")
    

    您可以对查询应用相同的过程

    $ID = 1;
    $DATA = $MYSQLI->real_escape_string($_POST['data']));
    $FIELD = "lifename";
    $DBQUERY = "UPDATE `lifetable` SET `$FIELD` = '$DATA' WHERE `id` = $ID";
    $DBRESULT = $MYSQLI->query($DBQUERY);
    

    我编辑了上面的内容,因为我忘记了问题中 lifename 的引号。它们应该在我的原始代码中。

    现在游览查询应该是安全的:D 这里是对 php.net 文档的参考: http://cn2.php.net/manual/en/mysqli.real-escape-string.php

    【讨论】:

    • 只要lifename 不是常量,这段代码就会抛出错误。避免 SQL 注入的最好方法是使用 PDO 类。因为它可以防止您可能遇到的所有问题。
    • 真的,我只是复制了上面的代码,没有检查输入,假设它已经在工作了 XD
    • 为什么不是? $ID 和 $FIELD 是硬编码的,所以我认为是类的属性或唯一有意义的数据是 $_POST['data'] 和 mysql_real_escape_string 提供针对 sql 注入的安全性...
    • 我的代码没有错误,我的代码工作正常,我没有说我的代码有错误,我说我想让它更安全,我不希望使用 PDO。 @Jurik
    • @YourCommonSense 以防你从未注意到,这就是我的问题!如果您想批评,请提供您自己的答案。谢谢
    猜你喜欢
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多