Bir e-posta adresini is_email () işlevine geçirmeden önce sterilize etmeli miyim?


13

is_email()Kullanıcı tarafından sağlanan bir e-posta adresinin geçerli olup olmadığını kontrol etmek için kullanıyorum . Örneğin:

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

Bildiğim kadarıyla, bu işlevdeki hiçbir şey bilgileri veritabanına yazmaz. İşleve $emailgeçirmeden önce dezenfekte etmeli miyim ?


Kaiser, düzenleme için teşekkürler. Aslında benim için
sanitasyon

Yanıtlar:


5

is_email()Trac üzerindeki işlevselliğe baktığımızda, sadece dize testi olduğu için sanatizie'ye ihtiyacınız yok gibi görünüyor. Hatta bu işlev doğruysa, veritabanına göndermeden önce onu sterilize etmeniz gerekmeyeceğini söyleyebilirim.


Dize testi ile ilgili düşüncelerim tam olarak. Sanırım db'ye göndermeden önce hala dezenfekte edeceğim, muhtemelen gerekli olmadığına haklısın, ama bu şeyler söz konusu olduğunda gergin bir enkazım :)
henrywright

Doğru, üzgün olmaktan daha güvenli ve sanitasyon yükü tamamen farkedilmez.
Howdy_McGee

18

WordPress ve PHP Çekirdeği

is_email()Fonksiyon Kaynak tipik bir WordPress uygulamasıdır ve hangi tamamen çalışmaz RFC 6531 tanır. Bunun bir nedeni, varsayılan PHP FILTER_VALIDATE_EMAILsabitinin filter_var(), Internet Engineering Task Force (IETF®) yönergelerine göre bir şeyi doğrulamakta çok daha iyi olmaması olabilir .

Standartlar

Buradaki nokta, RFC 6531'in "ASCII aralığının ötesindeki Unicode karakterlere" izin vermesidir . Yani bunlar (yerel kısım için - öncesinde @):

  • Büyük ve küçük İngilizce harfleri (a – z, A – Z) (ASCII: 65–90, 97–122)
  • Rakamlar 0için 9(ASCII: 48-57)
  • Bu özel karakterler: ! # $ % & ' * + - / = ? ^ _ ` { | } ~
  • Karakter .(nokta, nokta, tam durdurma) (ASCII: 46), ilk veya son karakter olmaması koşuluyla ve art arda görünmemesi koşuluyla (örn John..Doe@example.com. İzin verilmez).
  • Özel karakterlere kısıtlamalarla izin verilir. Onlar:
    • Boşluk ve "(),:;<>@[\](ASCII: 32, 34, 40, 41, 44, 58, 59, 60, 62, 64, 91–93)
    • Özel karakterler için kısıtlamalar, yalnızca tırnak işaretleri arasında yer almaları gerektiğinde kullanılmaları ve bunlardan 2 tanesinin (ters eğik çizgi ve tırnak işareti "(ASCII: 92, 34)) bir ters eğik çizgi \(ör. "\\"Ve "\"") .
  • Yerel bölümün her iki ucunda da parantezle yorumlara izin verilir; örneğin john.smith(comment)@example.comve (comment)john.smith@example.comher ikisi de eşdeğerdir "john.smith@example.com", ancak john.(comment)smith@example.comgeçersizdir.
  • U+007FUTF-8 olarak kodlanan yukarıdaki uluslararası karakterlere RFC 6531 izin verir, ancak posta sistemleri yerel parçalar atarken hangi karakterlerin kullanılacağını kısıtlayabilir.

ve global / domain bölümü için:

Bir e-posta adresinin alan adı kısmı katı kurallara uymalıdır: harfler, rakamlar, kısa çizgiler ve noktalardan oluşan bir ana bilgisayar adı gereksinimlerini karşılamalıdır. Buna ek olarak, etki alanı kısmı, jsmith@[192.168.2.1]veya gibi jsmith@[IPv6:2001:db8::1][]] köşeli parantez ile çevrili bir IP adresi değişmez olabilir.

Kaynak: Wikipedia

Geçerli olan nedir?

Bu, aşağıdaki gibi garip ancak geçerli e-posta adreslerine yol açabilir:

  • 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

Kaynak: php.net / author gt@kani.hu - bu yazının yazarı tarafından düzeltilen örnek

Sınırları

Yerel ve alan adı uzunluğu sınırları da vardır:

E-posta adreslerinin biçimi local-part@domain, yerel bölümün en fazla 64 karakter uzunluğunda olabileceği ve alan adının maksimum 253 karakterden oluşabileceği yerdir - ancak ileri veya geri yolun maksimum 256 karakterlik uzunluğu , tüm e-posta adresini olması en fazla 254 karakter uzunluğunda . [2] resmi tanımlar RFC 5322 olan (bölümler 3.2.3 3.4.1) ve RFC 5321 - bilgi RFC 3696 [3] ve ilgili doğrularını verilen daha okunabilir bir formu .

Kaynak: Wikipedia

WordPress kısıtlamaları

Ve WordPress aşağıdakileri kontrol eder:

  • E-postanın olabileceği minimum uzunluğu test edin: strlen( $email ) < 3
  • İlk konumdan sonra bir @ karakteri test edin: strpos( $email, '@', 1 ) === false
  • Geçersiz karakterleri test edin: !preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local )
  • Periyod dizileri için test: preg_match( '/\.{2,}/', $domain )
  • Ön ve arka dönemleri ve boşlukları test edin: trim( $domain, " \t\n\r\0\x0B." ) !== $domain
  • Alan adında en az iki alt öğe olacağını varsayalım: $subs = explode( '.', $domain );ve sonra
    • 2 > count( $subs )
    • trim( $sub, " \t\n\r\0\x0B-" ) !== $sub
    • !preg_match('/^[a-z0-9-]+$/i', $sub )

Kaynak: WP Core v4.0

Filtreler ve özel doğrulama

Yukarıda belirtilen tüm vakalar is_email()yanlış döndürmeyi tetikleyecektir . Sonuç filtreleme özelliğine sahiptir (geri arama eklenebilir) ve filtrenin üç bağımsız değişkeni olacaktır; burada son argüman nedendir. Misal:

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

Bu, belirli denetimlerle döndürülen sonuçları geçersiz kılabileceğiniz anlamına gelir.

Bu, örneğin Umlaut alan adlarına, yalnızca TLD alan adlarına vb. İzin vermek için özel kontroller eklemenize olanak tanır.

Sonuç

WordPress çoğu durumda güvenlidir, ancak posta sunucularının RFC uyumlu olması gerektiğinden daha kısıtlayıcıdır. Her posta sunucusunun RF 6531 yönergelerine uygun olmayacağını unutmayın.

Düzenle

Komik yan etki: İçinde iki ilgili işlev vardır ~/wp-includes/formatting: is_email()ve sanitize_email(). Pratik olarak aynı işlevlerdir. Neden birisi sadece diğer sağlar filtreleri geri arama olarak eklemek yerine işlev içeriğini birinden diğerine kopyalamak için iyi bir fikir olacağını karar bir fikrim yok. As v0.71 beri ve v1.5 beri aynıdır bir temizlenmiş dize olsun, ben şahsen daha sonra kullanmak. Not olduğunu o RFC uyumlu olmadığını hatta devletler.is_email() sanitize_email() is_email()


Yani teorik olarak, RFC 6531'e göre tamamen geçerli olan e-posta adresleri olacağını söylüyorsunuz, ancak bunlar WordPress tarafından geçersiz sayılacak mı?
henrywright

Bazıları evet. Örneğin, yalnızca TLD alanları, imleç alanları vb., Yanıtın sonucundan önceki son paragrafta okuyabileceğiniz gibi. Lütfen cevabı tekrar okuyunuz. Kafanı sarmanın çok şey olduğunu biliyorum, ama buna değer.
kaiser

1
Aslında zaten iki kez okudum, çünkü bu anlaşılmaya değer bir şey! Bu kadar ayrıntılı bir cevap için teşekkürler :)
henrywright

2

Her şeyi sterilize edin!

Temel güvenlik kurallarından biri, kullanıcıdan gelen girdilere asla güvenmemektir. Genel olarak, is_email () veya başka bir özel fonksiyonun uygulanması veya bu fonksiyonun verdiğim şeyle tehlikeli bir şey yapması umurumda değil. Belki uygulama bir gün değişecektir. Kim bilir. Ödün verilebileceğini varsaymalıyım. Varsayım her zaman kullanıcı girişinin aktif olarak düşmanca, iki katına çıkacak ve sonunda bir veritabanı için hedeflenen herhangi bir şey için ve bir kullanıcı işlevine teslim etmeden önce her kullanıcı girdisini sterilize etmesi olmalıdır. Bu sadece iyi, genel güvenlik hijyeni.


Uygulamanın değişip değişmeyeceğini asla söylemediğini söylediğinde kafasına çiviyi vurduğunu düşünüyorum. Şimdi sterilize etmemek uygun olabilir, ancak bunun daha sonraki bir tarihte değişip değişmeyeceğini kim bilebilir?
henrywright
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.