Мне интересно, если бы я использовал именованные параметры только для ввода пользователя или мне нужно сделать это для всех, например
$id = $_POST['id'] ;
$update = $conn->prepare("UPDATE users SET profile ='reset',
status='closed' WHERE id = :id ") ;
$update->bindValue(":id",$id,PDO::PARAM_INT) ;
$update->execute() ;
Я использовал именованные параметры для идентификатора, потому что это ввод пользователя, а что касается профиля, статус, который вводится мной, это плохо и небезопасно? Должен ли я использовать именованные параметры для тех, кто
Неправильно думать, что вам нужно беспокоиться только о пользовательском вводе.
Ваш код может получить небезопасный контент из любого источника, например:
Это верно, даже данные, которые были безопасно вставлены в вашу собственную базу данных, могут стать небезопасным контентом.
Пример: Предположим, вы хотите найти всех пользователей, имена которых совпадают с именем пользователя 123 (я знаю, что это можно сделать с помощью JOIN, но это всего лишь пример, так что потерпите меня):
$name = $conn->query("SELECT name FROM users WHERE id=123")->fetchColumn();
$data = $conn->query("SELECT * FROM users WHERE name = '$name'")->fetchAll();
Это безопасно? $name
это то, что я выбрал из базы данных, и мы предполагаем, что он был вставлен безопасно ранее. Как данные в моей собственной базе данных могут представлять риск для внедрения SQL?
Что если имя «О’Рейли»? Это приведет к тому, что второй запрос будет иметь синтаксическую ошибку по крайней мере, потому что одинарные кавычки будут несбалансированными.
Технически это SQL-инъекция, хотя риск, скорее всего, будет простой ошибкой, чем любая зловещая попытка взлома.
С другой стороны, были реальные случаи, когда хакер намеренно регистрировал свое «имя» на веб-сайте таким образом, что он использовал SQL-инъекцию или межсайтовый скриптинг. Когда имя злоумышленника позже использовалось веб-сайтом в каком-либо другом запросе или веб-выводе, он успешно завершил взлом. Я не шучу.
Решение, как обычно, заключается в использовании подготовленного оператора с параметром запроса:
$stmt = $conn->prepare("SELECT * FROM users WHERE name = ?");
$stmt->execute([$name]);
$data = $stmt->fetchAll();
Предположение, что SQL-инъекция происходит только из пользовательского ввода, напоминает мне эту цитату:
«Объяснения существуют; они существовали всегда; всегда есть хорошо известное решение каждой человеческой проблемы — аккуратное, правдоподобное и неправильное». — Х. Л. Менкен
Это небезопасно, только если вы принимаете пользовательский ввод и не избегаете его каким-либо образом.
Ваши собственные входы, которые не происходит от $_POST
, $_GET
, $_COOKIE
или же $_REQUEST
полностью безопасны
редактировать Как указывает Билл Карвин, существуют и другие потенциальные источники опасности. Я думаю, я должен уточнить мою точку зрения, чтобы сказать:
Не доверяйте никаким источникам данных которые могли быть испорчены пользовательским вводом