Intereting Posts

Должен ли я дезинфицировать адрес электронной почты, прежде чем передавать его функции is_email ()?

Я использую is_email() чтобы проверить, действительно ли предоставленный пользователем адрес электронной почты действителен. Например:

 $email = $_POST['email']; if ( is_email( $email ) ) // Do something. 

Насколько мне известно, ничто в этой функции не записывает информацию в базу данных. Должен ли я дезинформировать $email прежде чем передать ее функции?

Если посмотреть на is_email() на trac, похоже, вам не нужно санацизировать, поскольку это просто тестирование строк. Я даже зашел так далеко, чтобы сказать, что если эта функция вернёт true, вам не нужно санировать ее перед отправкой в ​​базу данных.

Ядро WordPress и PHP

Функция is_email() Source является типичной реализацией WordPress и не работает полностью с тем, что позволяет RFC 6531 . Одна из причин может заключаться в том, что константа PHP FILTER_VALIDATE_EMAIL по умолчанию для filter_var() не намного лучше filter_var() что-то в соответствии с руководящими принципами Целевой группы Internet Engineering (IETF®) .

стандарты

Точка в том, что RFC 6531 позволяет «символы Unicode за пределами диапазона ASCII» . А именно, это (для локальной части – до @ ):

  • Верхние и строчные английские буквы (a-z, A-Z) (ASCII: 65-90, 97-122)
  • Цифры от 0 до 9 (ASCII: 48-57)
  • Эти специальные символы ! # $ % & ' * + - / = ? ^ _ ` { | } ~ ! # $ % & ' * + - / = ? ^ _ ` { | } ~
  • Персонаж . (точка, период, полная остановка) (ASCII: 46) при условии, что он не является первым или последним символом и также предусматривает, что он не появляется последовательно (например, John..Doe@example.com не допускается).
  • Специальные символы допускаются с ограничениями. Они есть:
    • Пространство и "(),:;<>@[\] (ASCII: 32, 34, 40, 41, 44, 58, 59, 60, 62, 64, 91-93)
    • Ограничения для специальных символов заключаются в том, что они должны использоваться только в том случае, если они заключены между кавычками, и что двум из них (обратная косая черта и кавычка) (ASCII: 92, 34) также должна предшествовать обратная косая черта \ (например, "\\" и "\"" ).
  • Комментарии допускаются с круглыми скобками на обоих концах локальной части; например john.smith(comment)@example.com и john.(comment)smith@example.com , оба эквивалентны "john.smith@example.com" , но john.(comment)smith@example.com недействителен ,
  • Международные символы выше U+007F , закодированные как UTF-8, разрешены RFC 6531, хотя почтовые системы могут ограничивать использование символов при назначении локальных частей.

и для глобальной / доменной части:

Часть имени домена для адреса электронной почты должна соответствовать строгим правилам: она должна соответствовать требованиям к имени хоста, состоящему из букв, цифр, дефис и точек. Кроме того, часть домена может быть литералом IP-адреса, окруженным квадратными скобками, такими как jsmith@[192.168.2.1] или jsmith@[IPv6:2001:db8::1] […]

Источник: Википедия

Что действительно?

Это может привести к странным, но действительным адресам электронной почты, например:

  • localpart.ending.with.dot.@example.com
  • (comment)localpart@example.com
  • "this is v@lid!"@example.com
  • "much.more unusual"@example.com
  • postbox@com
  • admin@mailserver1
  • "()<>[]:,;\\@\"\\\\!#$%&\'*+-/=?^_`{}| ~.a"@example.org
  • " "@example.org

Источник: php.net / author gt@kani.hu – пример, установленный автором этой публикации

рамки

Существуют также ограничения по локальной и доменной длине:

Формат адресов электронной почты является local-part@domain где локальная часть может содержать до 64 символов, а имя домена может содержать не более 253 символов, но максимальная длина 256-символьного пробега прямого или обратного пути ограничивает весь адрес электронной почты должен содержать не более 254 символов . [2] Официальные определения приведены в RFC 5322 (разделы 3.2.3 и 3.4.1) и RFC 5321 – с более читаемой формой, приведенной в информационном RFC 3696 [3 ] и связанные с этим ошибки.

Источник: Википедия

Ограничения WordPress

И это то, что WordPress проверяет:

  • Тест на минимальную длину электронной почты может быть: strlen( $email ) < 3
  • Тест для символа @ после первой позиции: strpos( $email, '@', 1 ) === false
  • Тест на недопустимые символы !preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local )
  • Тестирование последовательностей периодов: preg_match( '/\.{2,}/', $domain )
  • Проверка начальных и конечных периодов и пробелов: trim( $domain, " \t\n\r\0\x0B." ) !== $domain
  • Предположим, что у домена будет как минимум два подмножества: $subs = explode( '.', $domain ); а потом
    • 2 > count( $subs )
    • trim( $sub, " \t\n\r\0\x0B-" ) !== $sub
    • !preg_match('/^[a-z0-9-]+$/i', $sub )

Источник: WP Core v4.0

Фильтры и пользовательская проверка

Все вышеупомянутые случаи is_email() чтобы вернуть false. Результат является фильтруемым (обратный вызов может быть присоединен), и фильтр будет иметь три аргумента, где причиной является последний аргумент. Пример:

 return apply_filters( 'is_email', false, $email, 'sub_hyphen_limits' ); 

что означает, что вы можете переопределить результаты, возвращаемые определенными проверками.

Это позволяет вам добавлять специальные проверки, например, разрешать Umlaut-domains, только части домена только для домена и т. Д.

Вывод

WordPress безопасен для большинства случаев, но более ограничительный, поскольку на самом деле почтовые серверы должны быть совместимыми с RFC. Имейте в виду, что не каждый почтовый сервер будет соответствовать рекомендациям RF 6531.

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

Смешной побочный эффект: внутри ~/wp-includes/formatting есть две связанные функции: is_email() и sanitize_email() . Они практически одинаковы . Я понятия не имею, почему кто-то решил, что было бы хорошей идеей скопировать содержимое функции из одного поверх другого вместо того, чтобы просто добавить его в качестве обратного вызова к фильтрам, которые предоставляет другой. Как is_email() поскольку v0.71 и sanitize_email() так как v1.5 одинаковы, я лично буду использовать позже, когда вы получите очищенную строку. Обратите внимание, что is_email() даже утверждает, что он не соответствует RFC.

Санитировать все вещи!

Одно из основных правил безопасности – никогда не доверять входным данным пользователя. В общем, я не забочусь о реализации is_email () или любой другой конкретной функции, или если эта функция делает что-то опасное с тем, что я ей даю. Может быть, реализация однажды изменится. Кто знает. Я должен предположить, что это может быть скомпрометировано. Предположение всегда должно заключаться в том, что пользовательский ввод активно враждебный, вдвойне для всего, что в конечном итоге предназначено для базы данных, и для дезинфекции каждого бита пользовательского ввода, прежде чем передавать его некоторым функциям. Это просто хорошая гигиена общей безопасности.