ПОЛУЧИТЬ параметры, уязвимые для SQL-инъекции — PHP

#php #mysql #security #sql-injection

#php #mysql #Безопасность #sql-инъекция

Вопрос:

Меня попросили решить проблему безопасности для сайта, который был настроен другим программистом. На данный момент я еще не видел ни одного кода, поэтому на данном этапе я отхожу от предположений и хочу изложить свои основы. Группа, размещающая сайт, провела проверку безопасности и обнаружила, что у них есть код, уязвимый для SQL-инъекции.

Пример: www.example.com/code.php?pid=2amp;ID=35 (ПОЛУЧИТЬ идентификатор параметра уязвимо для SQL-инъекции)

Теперь, поскольку я новичок, я объяснил, что, скорее всего, смогу решить проблему с хостом, но их сайт все равно должен быть просмотрен кем-то, кто обладает более глубокими знаниями в области безопасности.

Итак, чтобы позаботиться о потенциальных SQL-инъекциях (и не видя кода), я бы использовал mysql_real_escape_string:

 $query = sprintf("SELECT * FROM table WHERE pid='%s' AND ID='%s'",
            mysql_real_escape_string($pid),
            mysql_real_escape_string($id));
  

Кроме того, я бы рассмотрел mysqli_real_escape_string и подготовленные инструкции, но я не знаю, как они настроены. Но будет ли mysql_real_escape_string заботиться о потенциальной SQL-инъекции?

Комментарии:

1. Вам было бы лучше использовать подготовленные инструкции.

Ответ №1:

По возможности пропустите старые mysql_* материалы и используйте PDO.

 $pdo = new PDO('mysql:host=localhost;dbname=whatever', $username, $password);

$statement = $pdo->prepare('SELECT * FROM table WHERE pid=:pid AND ID=:id');

$statement->bindParam(':pid', $_GET['pid']);

$statement->bindParam(':id', $_GET['id']);

$results = $statement->execute();

var_dump($results->fetchAll());
  

Ответ №2:

Эта функция должна работать нормально — ваши переменные заключены в одинарные кавычки в инструкции SQL, и любые одинарные или двойные кавычки будут экранированы.

Это означает, что ни одна из переменных не может «вырваться» из инструкции.

Ответ №3:

Да, mysql_real_escape_string() экранирует любые потенциально опасные символы. Если вы знаете, что аргументы являются числовыми, не помешало бы проверить это также с помощью is_numeric()

Вам также следует взглянуть на mysql::prepare — Это гарантирует, что выполняется только 1 оператор, и предотвратит дополнительные уязвимости SQL.

Ответ №4:

Если ID и PID являются целочисленными полями, почему бы не преобразовать их в int.

Таким образом, у вас обязательно будет номер, без SQL-инъекции :

 $pid = (int) $pid;
$id = (int) $id;
  

Ответ №5:

Это должно быть нормально, но я бы всегда рекомендовал использовать подготовленные инструкции.