Чи потрібно оздоровити електронну адресу, перш ніж передати її у функцію is_email ()?


13

Я використовую, is_email()щоб перевірити, чи вказана користувачем адреса електронної пошти. Наприклад:

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

Наскільки мені відомо, ніщо в цій функції не записує інформацію в базу даних. Чи слід проводити санітарну обробку, $emailперш ніж передати її на функцію?


Кайзер, дякую за редагування. Це насправді санітарія для мене, але я впевнений, що більшість читачів тут використовуватиме z :)
henrywright

Відповіді:


5

Дивлячись на is_email()функціональність на Trac, схоже, що вам не потрібно санаціювати, оскільки це лише тестування рядків. Я б навіть зайшов, щоб сказати, що якщо ця функція повернеться в істину, вам не потрібно буде її санітувати, перш ніж надсилати її в базу даних.


Мої думки саме про тестування струн. Я думаю, що я все-таки буду санітувати перед тим, як відправити в db, ти, мабуть, маєш рацію, що це не потрібно, але я знервований, коли справа стосується цих речей :)
henrywright

Правда, краще безпечно, ніж шкода, і санітарна обробка буде непомітною.
Howdy_McGee

18

WordPress та PHP ядро

is_email()Функція Source є типовою реалізацією WordPress і не повністю працювати з тим, що RFC 6531 дозволяє. Однією з причин може бути те, що FILTER_VALIDATE_EMAILконстанта PHP за замовчуванням filter_var()не є набагато кращою для перевірки чогось згідно з інструкціями Internet Engineering Task Force (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)
    • Обмеження для спеціальних символів полягає в тому, що вони повинні використовуватися лише тоді, коли вони містяться між лапками, і 2 з них (нахил \ та лапки "(ASCII: 92, 34)) також повинні передувати косою рисою \(наприклад, "\\"та "\"") .
  • Допускаються коментарі з дужками на будь-якому кінці локальної частини; наприклад , john.smith(comment)@example.comі (comment)john.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 / автор 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()до повернення помилок. Результат може працювати з фільтром (зворотний виклик може бути доданий), і до фільтра буде три аргументи, де причина останнього аргументу. Приклад:

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

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

Це дозволяє додавати спеціальні чеки, наприклад, щоб дозволити домени Umlaut, частини домену лише для TLD тощо.

Висновок

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

Редагувати

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


Отже, ви говорите, що теоретично там будуть адреси електронної пошти, які є повністю дійсними згідно з RFC 6531, але WordPress вважатиме їх недійсними?
henrywright

Деякі так. Наприклад, домени лише для TLD, доменів umlaut тощо, як ви можете прочитати в останньому абзаці перед висновком у відповіді. Будь ласка, прочитайте відповідь ще раз. Я знаю, що це багато, щоб загорнути голову, але це того варте.
кайзер

1
Я насправді вже читав це двічі, оскільки це щось, що варто розуміти! Дякую за таку детальну відповідь :)
henrywright

2

Санітируйте всі речі!

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


Я думаю, що ти вдарив цвях по голові, коли сказав, що ніколи не знаєш, чи зміниться імплементація. Це може бути нормально не санітувати зараз, але хто знає, чи зміниться це згодом?
henrywright
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.