Меня попросили обработать проблему безопасности для сайта, который был настроен другим программистом. На данный момент я не видел ни одного кода, поэтому сейчас я ухожу от предположений, и я хочу покрыть свои базы. Группа, на которой размещен сайт, провела проверку безопасности и обнаружила, что код был уязвим для SQL-инъекции.
Пример: www.example.com/code.php?pid=2&ID=35 (идентификатор параметра GET уязвим для 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?
Пропустите старый 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());
Эта функция должна быть в порядке – ваши переменные находятся внутри одинарных кавычек в инструкции SQL, и любые одиночные или двойные кавычки будут экранированы.
Это означает, что ни одна из переменных не может «вырваться» из инструкции.
Да, mysql_real_escape_string () избежит любых потенциально опасных символов. Если вы знаете, что аргументы являются числовыми, это не помешает проверить это, используя is_numeric ()
Вы также должны посмотреть на mysql :: prepare – это обеспечит выполнение только одного оператора и предотвратит дополнительные SQL-уязвимости.
Если идентификатор и PID являются целыми полями, почему бы не отнести их к int .
Таким образом, у вас обязательно будет номер, без SQL-инъекции:
$pid = (int) $pid; $id = (int) $id;
Это должно быть хорошо, но я всегда рекомендую использовать подготовленные заявления.