有很多种“X足以阻止SQL注入吗?”问题,但我找不到能够很好地解释这一具体问题的问题。
由于我无法在预准备语句中绑定列名的值,因此必须有一些其他安全的方法来接受用户输入以排序查询以及准备语句无效的其他类型的事物。如果我有$sort_column
我已经退出$_GET
,我显然不应该直接在查询中使用它。
$no = "SELECT col1, col2, col3 FROM table ORDER BY $sort_column;";
而不是仅仅转义$sort_column
并尝试运行查询,似乎我可以事先检查相关表的合法列名列表。这将让我告诉用户他们选择了一个无效的列而不需要从数据库错误中找出它。根据我的阅读,即使我这样做,使用$sort_column
而不逃避它仍然是不安全的,但我不明白,除非in_array
不能像我认为的那样工作。
$good_columns = array("col1", "col2", "col3");
if (in_array($sort_column, $good_columns, true)) {
$sql = "SELECT col1, col2, col3 FROM table ORDER BY $sort_column;";
如果我使用“安全”数组中的列名而不是使用用户提供的值,该怎么办?
function is_column($column, $good_columns) {
$key = array_search($column, $good_columns);
if ($key !== false) {
return $good_columns[$key];
}
return false;
}
$good_columns = array('col1', 'col2', 'col3');
$my_column = is_column($sort_column, $good_columns);
if ($my_column) {
$sql = "SELECT col1, col2 FROM tbl1 ORDER BY $my_column;";
我确实逃避了一切,我不是试图避免这样做或主张不这样做。我很好奇这样的事情是如何仍然容易受到攻击的。
答案 0 :(得分:1)
你这样做并不是不安全的,你当然可以这样做。问题在于您可能习惯于在之前验证变量,然后在向项目添加更多代码的过程中将它们直接插入到查询中。如果您错过了在代码中的某个位置检查变量,那么您将很容易找到错误或跟踪sql注入的来源。最好习惯在查询中使用它之前始终转义每个变量。