Kev*_*vin 2 php mysql sql-injection addslashes
我们正在从 php 5.3 升级到 5.4,它不向后兼容“get_magic_quotes_gpc”。我知道代码仍然可以工作,但每次都会返回一个 FALSE。
然而,我认为现在是时候从我们的代码中删除它了。
这是一个典型的例子:
$product_id = "0";
if (isset($HTTP_GET_VARS["id"])) {
$rid = (get_magic_quotes_gpc()) ? $HTTP_GET_VARS["id"] : addslashes($HTTP_GET_VARS["id"]);
}
//then $product_id gets used all over the place in many different queries
Run Code Online (Sandbox Code Playgroud)
我一直在研究如何解决这个问题,这就是我想到的:
$rid = "0";
if (isset($HTTP_GET_VARS["id"])) {
$rid = addslashes($HTTP_GET_VARS["id"]);
}
Run Code Online (Sandbox Code Playgroud)
我有点不知所措了。我知道这一切都与 SQL 注入等有关。我的解决方案合理/可接受吗?
提前致谢。
<<<<编辑-附加信息>>>>
感谢您的回复。实际上,我们大约 18 个月前进行了一系列到 PDO 的转换(主要是由于 stackoverflow 上的此类建议:)
所以,我可能有一些多余的、毫无意义的代码。下面是我上面发布的从 URL 获取变量的代码下面发生的情况的完整图片。
您会看到,曾经存在的 (get_magic_quotes_gpc) 现在已被注释掉并被 (addslashes) 取代。但该变量会传递给 PDO 查询。
$product_id = "0";
if (isset($HTTP_GET_VARS["id"])) {
//$product_id = (get_magic_quotes_gpc()) ? $HTTP_GET_VARS["id"] : addslashes($HTTP_GET_VARS["id"]);
$product_id = addslashes($HTTP_GET_VARS["id"]);
}
// NEW QUERIES - BEG xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
try {
# MySQL with PDO_MYSQL
$pdo = new PDO("mysql:host=$hostname_db;dbname=$database_db", $username_db, $password_db);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
// Query 1: product details
$stmt = $pdo->prepare('SELECT
[a bunch of stuff here, fields, joins, etc]
WHERE product_id = ? ');
$stmt -> execute(array($rid));
$row_count_resto_details = $stmt->rowCount();
$row_resto_details = $stmt->fetch(PDO::FETCH_ASSOC);
}
// Error message for pdo
catch(PDOException $e) {
echo $e->getMessage();
}
// END QUERY xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Run Code Online (Sandbox Code Playgroud)
我可以去掉前 4-5 行代码中的所有内容,然后将其设置为:
$product_id = $HTTP_GET_VARS["id"];
Run Code Online (Sandbox Code Playgroud)
不,这不合理。
问题是,“魔术引号”功能一开始就是一个坏主意,因此尝试复制它只意味着您到目前为止一直依赖于一个损坏的解决方案,并且您的应用程序无疑容易受到 SQL 注入攻击。
“为什么魔术引用是一个损坏的解决方案?”,您可能会问。答案就隐藏在问题本身中 - 安全和 IT 一般而言不是也不可能具有魔力。每当您看到一个自我宣传或至少看起来以“神奇”方式工作的解决方案时,请知道它很糟糕,并且您永远不应该相信它。
相反,您需要的是上下文感知的解决方案,而在防止 SQL 注入的情况下,那就是参数化查询。您应该阅读本文以了解更多信息:How can I Prevent SQL-injection in PHP?
我还强烈建议您直接升级到 PHP 5.6,主要有两个原因:
更新(回答扩展问题):
您不仅可以删除addslashes()逻辑,而且必须这样做 - 如果您保留它,它将向您的某些输入数据添加斜杠,并且这些斜杠将成为数据本身的一部分。
相反,您想要做的是验证输入数据 - 首先检查它的格式是否正确。例如,如果您需要数字 ID,请在使用前检查它是否仅包含数字。
另外,自 PHP 4.1 以来$HTTP_GET_VARS已被弃用,您应该改用它。$_GET