preg_match безопасный enaught во входе satinization?

Я создаю новое веб-приложение, среду ЛАМПЫ... Я задаюсь вопросом, можно ли preg_match доверять для контроля ввода пользователя (+, подготовил stmt, конечно) для всех основанных на тексте полей (иначе не поля HTML; телефон, имя, фамилия, и т.д.).

Например, для классического 'почтового поля', если я проверяю вход как:

$email_pattern = "/^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)" .
    "|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}" .
    "|[0-9]{1,3})(\]?)$/";

$email = $_POST['email'];
if(preg_match($email_pattern, $email)){
    //go on, prepare stmt, execute, etc...
}else{
    //email not valid! do nothing except warn the user
}

я могу спать легкий против инжекции SQL/XXS?

Я пишу regexp, чтобы быть более строгим, как они могут.

Править: как уже сказано, я уже действительно использую подготовленные операторы, и это поведение только для основанных на тексте полей (как телефон, электронные письма, имя, фамилия, и т.д.), таким образом, ничто, чему позволяют содержать HTML (для полей HTML, я использую HTMLpurifier).

На самом деле моя миссия состоит в том, чтобы позволить, передают входное значение, только если это соответствует моему regexp-white-list; еще, возвратите его назад пользователю.

p.s:: Я ищу что-то без mysql_real_escape_strings; вероятно, проект переключится на Postgresql в следующем будущем, так нужен в методе проверки, который является перекрестной базой данных ;)

5
задан Sayed Mohd Ali 14 November 2018 в 14:03
поделиться

7 ответов

Достаточно ли регулярного выражения для фильтрации, зависит от регулярного выражения. Если вы собираетесь использовать значение в операторах SQL, регулярное выражение должно каким-то образом запрещать ' и ". Если вы хотите использовать значение в выводе HTML и боитесь XSS, вам нужно убедиться, что ваше регулярное выражение не разрешает <, > и ".

Тем не менее, как уже неоднократно говорилось, вы не хотите полагаться на регулярные выражения, и, пожалуйста, из любви к $ deity, не надо! Используйте mysql_real_escape_string () или подготовленные операторы для ваших операторов SQL и htmlspecialchars () для ваших значений при печати в контексте HTML.

Выберите функцию очистки в соответствии с ее контекстом. Как правило, он лучше вас знает, что опасно, а что нет.


Отредактируйте, чтобы учесть ваше редактирование:

База данных

Подготовленные операторы == mysql_real_escape_string () для каждого значения, которое нужно ввести. По сути, это то же самое, за исключением повышения производительности в варианте подготовленных операторов и невозможность случайно забыть использование функции для одного из значений. Подготовленный оператор - это то, что защищает вас от SQL-инъекции, а не регулярное выражение. Ваше регулярное выражение может быть любым, и это не повлияет на подготовленный оператор.

Вы не можете и не должны пытаться использовать регулярные выражения для соответствия архитектуре «кросс-базам данных».Опять же, обычно система лучше знает, что для нее опасно, а что нет. Подготовленные заявления хороши, и если они совместимы с изменением, то вы можете спать спокойно. Без регулярных выражений.

Если это не так, а вы должны, используйте слой абстракции для своей базы данных, что-то вроде пользовательского $ db-> escape () , который в вашей архитектуре MySQL сопоставляется с mysql_real_escape_string () и в вашей архитектуре PostgreSQL соответствует соответствующему методу для PostgreSQL (я не знаю, какой из них не подойдет, извините, я не работал с PostgreSQL).

HTML

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

Замечание по безопасности

На самом деле, моя миссия - позволить передать входное значение, только если оно соответствует моему regexp-white-list; в противном случае верните его обратно пользователю.

Это может быть неверно для вашего сценария, но это просто общая информация: философия «возврата неверного ввода обратно пользователю» рискует открыть вас для отраженных XSS-атак .Пользователь не всегда является злоумышленником, поэтому, возвращая что-то пользователю, убедитесь, что вы все равно ускользнули от него. Просто нужно иметь в виду.

8
ответ дан 18 December 2019 в 07:28
поделиться

Существует php-функция mysql_real_escape_string (), которую, я считаю, вы должны использовать перед отправкой в ​​базу данных mysql, чтобы быть в безопасности. (Кроме того, его легче читать.)

1
ответ дан 18 December 2019 в 07:28
поделиться

Если вы хорошо разбираетесь в регулярных выражениях: да. Но, читая ваше регулярное выражение для проверки электронной почты, мне придется ответить нет.

Лучше всего использовать функции filter , чтобы относительно безопасно получать вводимые пользователем данные и обновлять php на случай, если в этих функциях обнаружится что-то сломанное. Когда у вас есть исходные данные input, вам нужно добавить некоторые вещи в зависимости от того, что вы делаете с этими данными: удалите \ n и \ r для заголовков электронной почты и http, удалите теги html для отображения пользователям, используйте параметризованные запросы для использования их с базой данных.

1
ответ дан 18 December 2019 в 07:28
поделиться

Для внедрения SQL вы всегда должны использовать правильное экранирование, например mysql_real_escape_string . Лучше всего использовать подготовленные операторы (или даже ORM), чтобы предотвратить пропуски. Вы это уже сделали.

Остальное зависит от логики вашего приложения. Вы можете фильтровать HTML вместе с проверкой, потому что вам нужна правильная информация, но я не выполняю проверку для защиты от XSS, я выполняю только бизнес-проверку *.

Общее правило - «фильтровать / проверять ввод, выводить экранировать». Поэтому я избегаю того, что показываю (или передаю третьему лицу), чтобы предотвратить теги HTML, а не то, что записываю.

* Тем не менее, имя или адрес электронной почты человека не должны содержать <>

5
ответ дан 18 December 2019 в 07:28
поделиться

Проверка заключается в приведении входных данных в соответствие с ожидаемыми значениями для вашего конкретного приложения.

Инъекции заключаются в том, чтобы взять необработанную текстовую строку и поместить ее в другой контекст без подходящего экранирования .

Это две совершенно разные проблемы, которые необходимо рассматривать отдельно, на разных этапах. Проверка должна выполняться при чтении ввода (обычно в начале скрипта); экранирование необходимо выполнять в тот момент, когда вы вставляете текст в контекст, например строковый литерал SQL, HTML-страницу или любой другой контекст, в котором некоторые символы имеют внеполосное значение.

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

Распространенная ошибка - запускать экранирование SQL или HTML для всего пользовательского ввода в начале скрипта. Даже учебники, ориентированные на безопасность (написанные дураками), часто советуют делать это. В результате неизменно получается большой беспорядок, а иногда и очень уязвимый.

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

Между прочим, это действительно плохое регулярное выражение для проверки электронной почты. В любом случае Regex не лучший инструмент для проверки электронной почты; сделать это правильно абсурдно сложно , но этот будет отклонять очень много совершенно правильных адресов, включая любые с + в имени пользователя, любые в .museum или .travel или любой из доменов IDNA. Лучше быть либеральным с адресами электронной почты.

3
ответ дан 18 December 2019 в 07:28
поделиться

НЕТ.

НЕЕЕТ.

НОООООООООООООООООООООООООООООООООО.

ДОЛЖНО. НЕТ. ИСПОЛЬЗОВАТЬ. РЕГЕКС. ДЛЯ. ЭТО. КОГДА-ЛИБО.

RegEx для обнаружения SQL-инъекции

Java - escape-строка для предотвращения SQL-инъекции

2
ответ дан 18 December 2019 в 07:28
поделиться

Вы все еще хотите исключить данные перед вставкой в базу данных. Хотя проверка пользовательского ввода является разумным решением, лучшей защитой от SQL-инъекций являются подготовленные операторы (которые автоматически экранируют данные) или экранирование с помощью встроенных функций экранирования базы данных.

1
ответ дан 18 December 2019 в 07:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: