URL кодирует и фильтрует дезинфицирующие проблемы вывода
Я пытаюсь выяснить, почему очищенная строка будет выводиться иначе, чем необработанная строка при кодировании URL.
Я не знаю, как это называется, но я искал кодирование и дезинфекцию URL и пробовал Google, но не могу найти никакого объяснения.
Я обнаружил это случайно после публикации видео, проблема в том, что я вставляю заголовки в базу данных, извлекаю их и создаю URL с ним.
Пример URL (который не работает из-за проблемы)
localhost/proviin/video/kojima%26%2339%3Bs+cancelled+masterpiece+-+investigating+silent+hills/16
Я сделал одностраничный тест, чтобы проверить, что происходит, и поведение, как вы можете видеть ниже.
Как мне нужен результат (но это не санировано):
$title = "Kojima's Cancelled Masterpiece - Investigating Silent Hills";
echo $title;
echo "<br>";
echo urlencode($title);
Выходы: (который будет работать в URL)
- Отмененный шедевр Кодзимы - расследование тихих холмов
- Kojima%27s+ Отменено + Шедевр +-+ Исследуя + Бесшумный +Hills
Как это
$title = sanitize("Kojima's Cancelled Masterpiece - Investigating Silent Hills", "str");
echo $title;
echo "<br>";
echo urlencode($title);
Выходы: (который не работает в URL, но очищен)
Отмененный шедевр Кодзимы - расследование тихих холмов
Kojima%26%2339%3BS + Отменено + Шедевр +-+ Исследуя + Бесшумный +Hills
Функция дезинфекции
function sanitize($item, $type) {
switch ($type) {
case "str":
return filter_var($item, FILTER_SANITIZE_STRING);
break;
case "mail":
return filter_var($item, FILTER_SANITIZE_EMAIL);
break;
case "url":
return filter_var($item, FILTER_SANITIZE_URL);
break;
case "int":
return filter_var($item, FILTER_SANITIZE_NUMBER_INT);
break;
case "float":
return filter_var($item, FILTER_SANITIZE_NUMBER_FLOAT);
break;
default:
return false;
}
}
Насколько я знаю:
Вы дезинфицируете данные перед вставкой в базу данных.
Вы убегаете (htmlspecialchars), когда вы эхо
Но почему санированные строки выводятся по-разному при использовании urlencode()
?
Если это нормальное поведение, как санировать строки перед их вставкой в таблицу базы данных и использовать их в URL с urlencode()
?
3 ответа
Вы дважды избегаете своих строк. Вы не должны передавать возвращаемое значение вашей функции очистки в urlencode()
, Оба экранируют данные, но по-разному, поэтому они не могут быть объединены в цепочку, как вы делаете здесь (не то, что любая escape-функция должна запускаться дважды в любом случае).
Так что нет, вам не нужно очищать данные таким образом, прежде чем вставлять их в базу данных. Вы должны избежать его, используя подготовленные операторы, чтобы он возвращался таким же образом при возврате из базы данных, готовый для urlencode()
или же htmlentities()
творить свою магию. Если вам не нужны данные, хранящиеся определенным образом, в этом случае preg_replace
наверное лучше.
Также помните, что пользовательский ввод также не должен unserialized()
по той же самой причине: http://php.net/manual/en/function.unserialize.php
Основная цель очистки перед добавлением в базу данных - избежать внедрения SQL. И одним из уязвимых символов является одиночная кавычка '
, Вот почему он заменяется другим символом, выглядящим так же, но без какого-либо влияния на базу данных.
Поэтому, когда вы дезинфицируете, вы заменяете уязвимые символы. А после URL-кодирования эти символы имеют разные коды. Чтобы предотвратить несовместимые URL-адреса, кодируйте строки всегда после очистки или, по крайней мере, после тех же действий.
Когда я использую вводимый текст для имени файла или папки, я использую эту функцию для его очистки.
/* urlsafe - Return a URL safe string */
public static function urlsafe($t)
{
$t = strtolower($t);
$t = preg_replace( "/[^a-z0-9]/", " ", $t);
$t = trim($t);
$t = preg_replace("/[ ]+/", "-", $t);
return($t);
}