У меня было это обсуждение с высокопоставленным парнем PHP :
PDO здесь бесполезен. а также mysql_real_escape_string. крайне низкое качество.
- Где использовать mysql_real_escape_string для предотвращения внедрения SQL?
- «Mysqli_real_escape_string» достаточно, чтобы избежать SQL-инъекций или других SQL-атак?
- SQL-инъекции в ADOdb и общая безопасность веб-сайта
- Почему использование подготовленного оператора mysql более безопасно, чем использование общих функций эвакуации?
- Предотвращение SQL-инъекций в PHP с помощью MDB2
Это, конечно, классно, но я честно не знаю, что не так с предложением использовать mysql_real_escape_string
или PDO для исправления этого кода:
<script type="text/javascript"> var layer; window.location.href = "example3.php?layer="+ layer; <?php //Make a MySQL connection $query = "SELECT Category, COUNT(BUSNAME) FROM ".$_GET['layer']." GROUP BY Category"; $result = mysql_query($query) or die(mysql_error());
В это
$layer = mysql_real_escape_string($_GET['layer']); $query = "SELECT Category, COUNT(BUSNAME) FROM `".$layer."` GROUP BY Category";
, учитывая, что код JavaScript отправляется на стороне клиента.
Ваш совет действительно неверен.
mysql_real_escape_string()
не будет работать для имен динамических таблиц; он предназначен для исключения строковых данных, ограниченных только кавычками . Он не ускользнет от обратного символа. Это небольшое, но важное различие.
Поэтому я мог бы вставить SQL-инъекцию в это, я просто должен был бы использовать закрывающий backtick.
PDO также не обеспечивает санитарию для имен динамических таблиц .
Вот почему хорошо не использовать динамические имена таблиц или, если нужно, сравнивать их со списком допустимых значений, например список таблиц из команды SHOW TABLES
.
Я тоже не знал об этом и, вероятно, виноват в том, что повторял тот же плохой совет, пока он не был указан мне здесь, на том же месте, также полковником Шрапнелом.
Для записи здесь приведен пример кода для фиксации этого отверстия.
$allowed_tables = array('table1', 'table2'); $clas = $_POST['clas']; if (in_array($clas, $allowed_tables)) { $query = "SELECT * FROM `$clas`"; }
Чтобы ответить, как исправить код:
'...FROM `' . str_replace('`', '``', $tableName) . '`...'
Это дублирует все обратные образы в имени таблицы (это делается в MySQL).
Одна вещь, о которой я не уверен, является ли это «безопасным для кодирования» (как правильно это назвать?). Обычно обычно используется mysql_real_escape_string
вместо mysql_real_escape_string
, потому что первая берет кодировку соединения MySQL. Может быть, эта проблема и здесь.