Я знаю, что данные следует очищать при их выводе или отображении, а НЕ при их получении или сохранении. Вот что я делаю сейчас:
echo htmlspecialchars($name, ENT_QUOTES);
Если я собираюсь получить параметры $_GET и проверить их в базе данных, должен ли я все еще очищать и экранировать? Например:
$name = htmlspecialchars($_GET['name'], ENT_QUOTES);
$stmt = $db->prepare("SELECT * FROM users WHERE name = :name");
$stmt->bindParam(':name', $name);
$stmt->execute();
Так нужен ли htmlspecialchars или мне просто нужно сделать $name = $_GET['name']?
Последовательно обрабатывать правила «безопасных данных» на месте использования - например. как используется в HTML. Неважно, исходит ли это от GET прямо или косвенно (через БД).






PDO делает это еще проще, чем вы:
$stmt = $db->prepare("SELECT * FROM users WHERE name = :name");
$stmt->execute([ 'name' => $_GET['name'] ]);
Вот и все. Сделанный.
Важно, чтобы вы не надо избегали вещей при использовании значений-заполнителей, особенно при сопоставлении. htmlspecialchars является Только релевантным в контексте HTML, за его пределами он наносит ущерб. Если вы показываете данные в формате JSON, в электронном письме или где-либо еще, экранируйте этот контекст и этот контекст Только.
Если у кого-то такое имя, как «A&W», то при поиске вы искажаете ввод и на самом деле ищете «A&W», которое не соответствует их имени. Они не получат совпадений, а затем спросят вас, что не так с вашим сайтом.
То, что вы должны сделать с входными данными Только, — это обрезать любые символы, которые могут помешать поиску, такие как начальные и конечные пробелы, которые кто-то мог ввести случайно.
Не используйте htmlspecialchars(). bind() выполняет все необходимое экранирование и цитирование.
PHP имеет запутанный набор эскейперов --
<input>, <textarea>, <a> — экранирует только "&<><pre>) — для работы с окончаниями строкmysql*.mysqli* — по крайней мере, '"\Что лучше всего использовать как правило при сохранении текста в таблице MySQL, так это экранировать строку ровно настолько, чтобы пройти парсер. Это экранирование исчезает по мере обработки. Оставьте акцентированные символы и т. д. в покое.
PHP PDO и mysqli имеют способы «привязки», которые делают всю работу за вас. Если вместо этого вы используете «интерполяцию» PHP, например
$sql = "SELECT * FROM t WHERE x = {$_GET['x']}";
у вас нет экранирования и защиты от SQL-инъекций. Не пишите код таким образом, если вы еще каким-то образом не проверили аргументы.
Для HTML вам нужен другой набор escape-последовательностей. Подумайте о <. Это вводит тег. Так как же отобразить «меньше чем»? Что ж, для этого вам понадобится «html-объект»: <. Это приводит к проблемам с &; следовательно, &.
Я бы сказал, не пишите такой период SQL, даже если вы проверили аргументы. Существуют способы введения вещей, которые при некоторых обстоятельствах могут обойти побег. Полное разделение данных и запросов — единственный гарантированно безопасный способ.
Вы по-прежнему должны быть проверка входными данными для целей целостности данных, например: убедитесь, что входные данные более или менее соответствуют вашим ожиданиям ради стабильности вашего приложения. Однако, поскольку вы используете подготовленные операторы, у вас нет насущной необходимости «санировать» [иначе говоря, «искажать»] ваши данные, поскольку они более строго инкапсулируются драйвером базы данных.
htmlspecialchars() делает данные безопасными для включения в документ HTML и должен использоваться только при выводе данных в документ HTML. Выполнение этого перед вставкой в базу данных более или менее загрязняет ваши данные для использования в чем-либо разное, кроме HTML-документа.
So is htmlspecialchars needed or should I just do $name = $_GET['name']?
Нет, это не нужно.
Сохраняйте входные данные как есть независимо от выходного носителя. Это не должно быть готовый для безопасного встраивания HTML.
Что, если завтра вам понадобятся эти данные в формате JSON для какого-нибудь API, PDF или десктопного приложения?
Только если он хранится в том же состоянии. Вы по существу изменяете данные, прежде чем сравнивать их с сохраненными данными. Если сохраненные данные не были изменены аналогичным образом, они не будут совпадать.