Alexander (HH): E-Mail-Validierung: Neuer Ansatz

Beitrag lesen

Moin Moin!

Hallo Alexander,

»» »» Hierbei möchte ich ausdrücklich NICHT prüfen, ob die E-Mail-Adresse logisch korrekt ist, sondern größeren Schaden verhindern.
»»
»» Was für Schäden?

Schäden der Form, wie ich sie beschrieben habe: Header Injections, Angabe mehrerer E-Mails auf ein Mal und Angabe mehrerer Strings, die alle eigentlich die selbe E-Mail-Adresse sind.

»» »» 2. Die Benutzung in der Funktion mail() soll möglich sein ohne Schaden anzurichten (Injenction).
»»
»» Wenn PHP selbst nicht vernünftig escapen kann, mußt Du es vorher machen.

Eben genau das ist mein Vorhaben.

Schade, dass PHP sich nicht um so essenzielle Sachen kümmert.

»» »» 4. Die E-Mail-Adresse soll eindeutig identifizierbar sein, damit nicht mehrfach die gleiche Adresse als Ziel verwendet wird.
»»
»» Welche der folgenden Adressen sind mit joe@example.com identisch? Welche füllen garantiert die selbe Mailbox?
»»
»» joe@example.com.

Das ist in der Tat eine interessante Angabe - eine einfache Regel hierfür wäre das Ausschließen von Punkten am Ende.

»» Joe@example.com
»» JOE@example.com
»» JOE@EXAMPLE.COM
»» joe@EXAMPLE.COM

Dies hätte mich sogar gar nicht betroffen, da ich MySQL zur Abfrage verwende. Dennoch ist dies ein wichtiger Punkt, falls Groß- und Kleinschreibung unterschieden wird.

Rechts des letzten @ nicht, links schon. Typische Mail-Provider arbeiten case insensitiv, aber die RFCs erlauben case sensitive Account-Namen. Joe@example.com, JOE@EXAMPLE.COM und joe@example.com sind bis zu drei verschiedene Mailboxen. joe@example.com und joe@EXAMPLE.COM sind dagegen identisch, ebenso JOE@EXAMPLE.COM und JOE@example.com.

»» joe+ipv6@example.com
»» joe-ipv6@example.com
»» joe@ipv6.example.com
»» joe@example.org
»» josef-maria.doe@example.com

Soweit ich das sehe sind dies alles unterschiedliche Adressen, die eventuell später auf die gleiche Mailbox verwaisen können - so etwas soll die Funktion nicht prüfen können. Und außerdem ist das praktisch nicht möglich.

Richtig.

»» »» - Es muss mindestens ein "@" vorkommen.
»»
»» - Nach dem letzten @ muß mindestens ein Punkt vorkommen, der nicht direkt am @ hängen darf.

Gute Regel - kann direkt aufgenommen werden, allerdings fehlt mir hier die Angriffsmöglichkeit.

joe@.example.com ist einfach keine gültige Mail-Adresse. Also gibt es auch keinen Grund, die weiter zu behandeln.

»» - Ein abschließender "." ist zwar selten, aber technisch korrekt.

Eben deshalb könnte ich ihn in meiner E-Mail-Validierung ausschließen.

Nein. s/.$//;

»» »» - Die Gesamtlänge darf 255 nicht überschreiten (willkürlich gewählt, um ein Limit zu setzen).
»»
»» Naja, gut, das kannst Du machen. Aber ein Limit ist in den RFCs nicht drin, soweit ich mich erinnere. Hostnamen haben eine Längenbegrenzung, Mail-Accounts nicht.

Meine Tabellenspalte in der Datenbank aber schon. ;)

Nimm text, dann brauchst Du Dir darum keine Sorgen mehr machen. ;-)

Und: Solche langen E-Mail-Adressen können allein schon deshalb ausgeschlossen werden, weil sie so selten vorkommen. Und wenn sie vorkommen, ist das in 99,9% der Fälle Absicht.

Naja, wer mit einer mehr als 80 Zeichen langen E-Mail-adresse geschlagen ist, wird sich wohl irgendwo eine kürzere besorgen.

Was aber durchaus vorkommen kann, sind viele Punkte rechts des letzten @. Ich hatte mal eine Adresse xxxxx@hermes.et-inf.xxxxxx.xxx. Auch können solche Adressen bei .uk und anderen TLDs mit fixen SLDs vorkommen: joe@stud.cs.u-bla.edu.tld

Möglich (aber zugegeben extrem selten) wären auch IP-Adressen: joe@127.128.129.130

»» »» - zu 4.) Die Zeichen "<" und ">" müssen ausgeschlossen werden, sonst sind Mehrfachnennungen der Form "Eva Mustermann 123@example.com" und "Adam Mustermann 123@example.com" möglich.
»»
»» s/^(.+)\s+<([^<>]+)>$/$2/;

Ich könnte natürlich auch einfach das Vorkommen jeglicher "<" und ">" in der Adresse verbieten - das würde meine Regel (1) erfüllen. So ein regulärer Ausdruck ist zwar auch ganz schick und schnell geschrieben, jedoch später schwer nachzuvollziehen wenn man sich länger nicht damit beschäftigt hat.

OK, laß mich die Codezeile verbessern:
s/^(.+)\s+<([^<>]+)>$/$2/; # extract e-mail address from "name e-mail@address"

CPAN hat dafür übrigens zwei fertige Module: Email::Valid zum Testen und Email::Address zum Parsen.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".