Очистка данных пользователя в GET с помощью PHP

Как вы дезинфицируете данные в $ _GET-переменных с помощью PHP?

Я дезинфицирую только одну переменную в GET с помощью strip_tags . Я не уверен, должен ли я вообще дезинформировать или нет, потому что в прошлый раз при отправке данных в Postgres проблему легче всего решить с помощью pg_prepare .

    Как вы дезинфицируете данные в $ _GET-переменных с помощью PHP?

    Вы не дезинфицируете данные в $ _GET. Это общий подход в PHP-скриптах, но это совершенно неправильно *.

    Все ваши переменные должны оставаться в текстовой форме до момента, когда вы вставляете их в другой тип строки. Нет никакой формы экранирования или «дезинфекции», которая может охватывать все возможные типы строк, в которые вы могли бы включить ваши значения.

    Поэтому, если вы встраиваете строку в SQL-запрос, вам нужно избегать ее на выходе:

     $sql= "SELECT * FROM accounts WHERE username='".pg_escape_string($_GET['username'])."'"; 

    И если вы выплевываете строку в HTML, вам нужно ее избежать:

     Cannot log in as <?php echo(htmlspecialchars($_GET['username'], ENT_QUOTES)) ?>. 

    Если вы сделали оба этих шага выхода из массива $ _GET в начале, как рекомендовано людьми, которые не знают, что они делают:

     $_GET['username']= htmlspecialchars(pg_escape_string($_GET['username'])); 

    Затем, когда у вас было «&» в вашем имени пользователя, таинственно превратится в «& amp;». в вашей базе данных, и если у вас был апостроф в вашем имени пользователя, он превратился бы в два апострофа на странице. Тогда, когда у вас есть форма с этими символами, в этом случае легко закончить двойное экранирование, когда они редактируются, поэтому многие плохие PHP CMS заканчиваются сломанными заголовками статей, такими как «Новые книги из O \\\\ \\\\\\\\\\\\\\\ 'Reilly».

    Естественно, помня о pg_escape_string или mysql_real_escape_string и htmlspecialchars каждый раз, когда вы отправляете переменную, это немного утомительно, поэтому каждый хочет сделать это (неправильно) в одном месте в начале скрипта. Для вывода HTML вы можете, по крайней мере, сохранить некоторую типизацию, определив функцию с коротким именем, которое выполняет эхо (htmlspecialchars (…)).

    Для SQL вам лучше использовать параметризованные запросы. Для Postgres есть pg_query_params . Или действительно, подготовленные заявления, как вы упомянули (хотя я лично считаю их менее управляемыми). В любом случае вы можете забыть о «дезинфекции» или утечке для SQL, но вы все равно должны избегать, если вы вставляете другие типы строк, включая HTML.

    strip_tags () не является хорошим способом обработки ввода для отображения HTML. Раньше у него были проблемы с безопасностью, поскольку анализаторы браузеров на самом деле намного сложнее в интерпретации того, что может быть тегом, чем вы могли бы подумать. htmlspecialchars () почти всегда правильная вещь, чтобы использовать вместо этого, так что, если кто-то набирает меньше, чем знак, они фактически получат буквальный знак меньше, чем знак, и не найдут наполовину их текст, таинственно исчезающий.

    (*: как общий подход к решению проблем с инъекциями, в любом случае. Естественно, существуют определенные для домена проверки, которые стоит делать в определенных полях, и есть полезные задачи очистки, которые вы можете сделать, например, удаление всех управляющих символов из представленных значений. не то, что большинство PHP-кодеров означает санитария.)

    Если вы говорите о дезинфекции вывода, я бы порекомендовал хранить содержимое в вашей базе данных в его полной, неэкранированной форме, а затем избегать ее ( htmlspecialchars или что-то еще), когда вы эхом отдаете данные, тем самым у вас есть больше возможностей для вывода. См. Этот вопрос для обсуждения санитарии / экранирования содержимого базы данных.

    Что касается хранения в postgres, используйте pg_escape_string для каждой переменной в запросе, чтобы избежать кавычек и, как правило, защищать от SQL-инъекции.

    Редактировать:

    Мои обычные шаги для хранения данных в базе данных, а затем их получения:

    1. Вызовите функцию экранирования данных базы данных (pg_escape_string, mysql_escape_string и т. Д.), Чтобы избежать каждой входящей переменной $ _GET, используемой в вашем запросе. Обратите внимание, что использование этих функций вместо addlashes приводит к отсутствию лишних косых черт в тексте при сохранении в базе данных.

    2. Когда вы возвращаете данные из базы данных, вы можете просто использовать htmlspecialchars для любых выводимых данных, не нужно использовать stripslashes, так как не должно быть никаких дополнительных косых черт.

    Вы должны дезинфицировать все запросы, а не только POST как GET.

    Вы можете использовать функцию htmlentities () , функцию preg_replace () с регулярным выражением или фильтр с помощью cast:

     <? $id = (int)$_GET['id']; ?> 

    [] 'S

    Санируйте свои входы в зависимости от того, куда он идет.

    • Если вы отобразите его (на странице или в качестве значения поля ввода), используйте htmlspecialchars и / или str_replace .
    • Если вы используете его как другой тип, произведите его.
    • Если вы включите его в SQL-запрос, сбегите его с помощью соответствующей функции, возможно, разделите html-теги, если хотите, чтобы они были полностью удалены (что не совпадает с экранированным).

    То же самое для POST или даже данных из вашей БД, поскольку данные внутри вашей БД вообще не должны быть экранированы.

    Две вещи, которые вы должны проверить:

    1. Кодирование вашего ввода по отношению к вашей таблице скриптов / вывода / базы данных PHP
    2. Если вы включили [magic_quotes_gpc][1] , вы должны либо отключить его (когда это возможно), либо stripslashes() GET, POST и COOKIE. magic_quotes_gpc устарел, вы должны дезинфицировать данные, которыми вы управляете, в зависимости от использования этих данных.