XHTML SVG CSS PHP

Dr. O. Hoffmann

PHP-Labor

Ein Anonymus aus Tibris
Sendet Palman ein Exlibris.
Auf demselben sieht man nichts
Als den weißen Schein des Lichts.
Nicht ein Strichlein ist vorhanden.
Palman fühlt sich warm verstanden.
Und klebt die Blättlein rein
Allenthalben dankbar ein.
Christian Morgenstern (Exlibris)

email-Maskierung

Wer kennt sie nicht, die spam-mails und die Frage, woher kennen die Idioten bloß meine Adresse? Gut, meist hat man sie dann doch in irgendeinem Forum oder bei einem Gewinnspiel angegeben. Aber laut Gesetz ist im Impressum auch eine Möglichkeit der elektronischen Kontaktaufnahme vorgesehen. Da solch ein Impressum auch unmittelbar zugänglich sein muß, kommen dort auch keine Spielereien mit java-script oder captchas in Frage, da solch ein Impressum auch ohne dieses komplett funktionieren muß.
Auch die email in einem Bild zu verstecken, entspricht nicht der unmittelbaren Zugänglichkeit - dafür müßte die email dann wieder alternativ als Klartext angegeben werden, was das Bild hochgradig überflüssig macht. Nun muß man zwar die Möglichkeit zur elektronischen Kontaktaufnahme nicht als email-Adresse interpretieren, wenn aber die Entscheidung darauf gefallen ist, möchte man dieses gern vor jenen (Ro)bot(ern) verbergen, die durch das internet jagen, um nach gültigen email-Adressen für spam zu suchen.
Man kann sich auch die Frage stellen, ob nicht auch ein Kontaktformular eine Möglichkeit der elektronischen Kontaktaufnahme ist. Sofern das Formular funktioniert und nicht durch Ausfälle etwa einer Datenbank oder eines email-Versenders außer Gefecht gesetzt werden kann, vermutlich schon (man Frage seinen Anwalt oder Abmahner).

Der traditionelle und etwas unkreative Ansatz liegt darin, sich nicht offensiv zu wehren, sondern eine extra-email-Adresse anzulegen nur für das Impressum. Da guckt man dann gelegentlich rein, ob vielleicht doch etwas anderes als spam bei dieser Adresse ankommt. Nachteil für die ernsthaften email-Schreiber ist natürlich, daß auch leicht mal eine ernsthafte Zuschrift unter all dem spam übersehen wird. Für ein Impressum ist das natürlich nicht optimal, aber da sind Gesetzgeber, Autoren und Nutzer letztlich alle Opfer der Spammer.

Zweiter Ansatz ist nun, die email-Adresse mittels einer XHTML-Maskierung zu verbergen. Die bösen Roboter suchen bislang nur nach nicht-maskierten Adressen, wobei sie besonderen Wert auf das @ legen und vermutlich auch auf die Zeichenfolge mailto. Es ist recht einfach, die Adresse mit PHP zu maskieren, es geht auch ohne PHP, aber dann muß man die ASCII-, ISO-Kodierung oder den Unicode kennen und das zu Fuß realisieren. Entsprechende Tabellen gibt es übrigens zum Beispiel bei selfhtml oder stattdessen hier die email-Adresse maskieren.
Garantieren kann natürlich niemand, daß die Roboter nicht vielleicht doch irgendwann mal auch nach solchen maskierten Adressen zu suchen lernen, deshalb sollte man die Methode mit dem ersten Ansatz oder dem folgenden kombinieren.

Hier ist das Beispiel, einem Kommentar zum PHP-Handbuch entnommen, etwas ergänzt und kommentiert, man achte auch auf den Quelltext der Ausgabe:
email-Maskierung mit XHTML

Schauen wir uns einfach einmal den PHP-Quelltext an, neben der Maskierung sehen wir auch ein schönes Beispiel für die sinnvolle Anwendung selbstdefinierter Funktionen:

<?php
# php-Labor: email-Adressen vor boesen bots durch
# Maskierung verbergen
# sollte funktionieren fuer email-Adressen, die nur
# aus ascii-Zeichen bestehen.
#
# Die Funktion wurde einem Nutzer-Kommentar des php-Handbuchs
# entnommen, geringfuegig modifiziert und kommentiert.
#
# Fehlerbericht anschalten:
error_reporting(E_ALL);
# Funktion, Eingabe:
# $strEmail - die email-Adresse
# $strDisplay - auszugebender Text in einem Verweis
# $strTitle - ggf Titleattribut im Verweis
# $blnCreateLink - true, false - Verweis kreiren oder nicht...
function Emailkodierung($strEmail,$strDisplay,$strTitle,$blnCreateLink) {
    # per Hand mailto: maskiert
    $strMailto = "&#109;&#097;&#105;&#108;&#116;&#111;&#058;";
    # Schleife, um email-Adresse zu maskieren 
    $strEncodedEmail="";    
    for ($i=0; $i < strlen($strEmail); $i++) {
        # ord gibt den ascii-Wert des ersten Zeichens eines strings zurueck
	# dieser string ist der substring ab Position $i der email-Adresse
        $strEncodedEmail .= "&#".ord(substr($strEmail,$i)).";";
    }
    # gucken, ob Text auszugeben ist
    if(strlen(trim($strDisplay))>0) {
        $strDisplay = $strDisplay;
    }
    # wenn nicht, dann kodierte email als Verweistext verwenden
    else {
        $strDisplay = $strEncodedEmail;
    }
    # gucken ob ein title-Attribut gesetzt werden soll und es erzeugen
     if(strlen(trim($strTitle))>0) {
        $strTitle = "title=\"$strTitle\"";
    }
    # sonst leeren string definieren
    else {
        $strTitle = "";
    }   
    # falls ein Verweis zurueckgegeben werden soll...
    if($blnCreateLink) {
        return "<a href=\"".$strMailto.$strEncodedEmail."\" $strTitle>".$strDisplay."</a>";
    }
    # falls aber nicht...
    else {
        return $strDisplay;
    }
 }
 # Das war die Funktion, die alles konvertiert, unten der Aufruf an der
 # Stelle, wo man es braucht...
 #
 # xhtml-Seite ausgeben:
echo"<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?> \n";
?>
<!DOCTYPE
 html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
<head>
<title>Dr. Olaf Hoffmann - email-Kontakt</title>
 </head>
<body>
<h1>Schreib mir eine email</h1>
<ul>
 <?php
 #Beispiele:
 echo "<li>\n";
 echo Emailkodierung("dr.o.hoffmann@gmx.de","email an: Dr. O. Hoffmann","",true);
 echo "</li>\n<li>";
 echo Emailkodierung("dr.o.hoffmann@gmx.de","Dr. O. Hoffmann","email an:",true);
 echo "</li>\n<li>";
 echo Emailkodierung("dr.o.hoffmann@gmx.de","","meine email",true);
 echo "</li>\n<li>";
 echo Emailkodierung("dr.o.hoffmann@gmx.de","","",false); 
 echo "</li>\n";
 ?>
</ul>
 <h2>Quelltext zum zweiten Beispiel</h2>
 <div>
 <pre>
 <?php
 #Beispiel:
echo htmlentities(Emailkodierung("dr.o.hoffmann@gmx.de","Dr. O. Hoffmann","email an:",true));
 ?>
 </pre>
 </div>
</body>
</html>

Als weiterer Ansatz wollen wir uns zunutze machen, daß spam-Roboter selten Formulare ausfüllen, schon gar nicht, wenn sie mit der Methode POST verschickt werden. Nach Betätigen des Abschickeknopfes erzeugt das PHP-Skript entweder mit der header-Funktion direkt einen Aufruf des email-Programmes oder aber die Ausgabe der email als einfacher Verweis. Ersteres geht natürlich nur, wenn das Darstellungsprogramm des Nutzers entsprechend konfiguriert ist, daher ist immer eine Auswahl beider Möglichkeiten anzugeben:

email-Adresse verbergen mit einem Formular

Schauen wir uns einfach einmal den PHP-Quelltext an:

<?php
# php-Labor: email-Adressen vor boesen bots durch
# Ausgabe mit eine Formular verbergen
#
# Fehlerbericht anschalten:
error_reporting(E_ALL);
#
# welche Adressen kommen in Frage?
$i=1;
$kuerzel[$i]="Doktor";
$adresse[$i++]="dr.o.hoffmann@gmx.de";  
$kuerzel[$i]="Prinz";
$adresse[$i++]="dpug@gmx.de";  
# weitere hierueber anhaengen
$anz=$i-1;
#
#  gewuenschte Adresse einlesen               
$wer="keiner";
if (isset($_POST['wer'])) {
$wer=$_POST['wer'];
} else {
# wenn nicht gesetzt, dann ungueltig machen
$wer="?!postmeister!?";
}
# gucken, ob ein gueltiger Adressat angegeben wurde
$ausgabe=FALSE;
for ($i = 1; $i <= $anz; $i++) {
if ($wer ==$kuerzel[$i]){
$ausgabe=true;
$email=$adresse[$i];
}
}
# Methode fuer die Ausgabe einlesen
$wie="html";
if (isset($_POST['wie'])) {
$wie=$_POST['wie'];
} else {
$wie="html";
}
# es gibt nur zwei gueltige Methoden...
if ($wie !="html"){
$wie = "direkt";
}
# tja direkt das email-Programm aufrufen?
if (($wie =="direkt") and $ausgabe){
 header("Location: mailto:$email"); 
 exit; 
# oder doch was per xhtml ausgeben?                                      
} else {
# xhtml-Seite ausgeben:
echo"<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?> \n";
?>
<!DOCTYPE
 html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
<head>
<title>Email-Adresse einblenden per Formular</title>
</head>
<body id="body"> 

<h1> email-Adresse einblenden mit einem Formular</h1>

<div>
<?php
# falls ein gueltiger Adressat angegeben wurde, die email-Adresse rausruecken...
if ($ausgabe) {
 echo "<a href=\"mailto:$email\" title=\"email senden\">mail an: $email</a> \n";
# sonst Auswahlformular ausgeben:  
} else {
?>
<form action="emailformular.php" method="post">
<div><input type="radio" name="wie" value="direkt" />email-Programm direkt aufrufen 
(nur wenn browser geeignet konfiguriert; bitte einen Moment warten)</div>
<div><input type="radio" name="wie" value="html" checked="checked" />nur 
email-Adresse als Verweis angeben</div>
<?php
# gueltige Adressaten angeben
for ($i = 1; $i <= $anz; $i++) {
echo "<div><input type=\"submit\" name=\"wer\" value=\"$kuerzel[$i]\" /></div> \n";
}
# zur Demonstration, wenn jemand versucht, ueber ein eigenes Formular eine Manipulation
# vorzunehmen.
?>
<div><input type="submit" name="wer" value="Ung&uuml;ltiges Beispiel" /></div>
</form>
</div>
<?php
}
?>
</body>
</html>
<?php
}
?>

Die Beispiele können natürlich leicht erweitert werden, wenn auch die Telephonnummer angegeben werden soll oder aber auch für die ebenfalls vorgeschriebene Postadresse vor Robotern verborgen werden soll.
Das Telephon ist ja inzwischen auch schon von Spammern betroffen, nur eine Frage der Zeit, bis es auch Roboter gibt, die Postadressen sammeln.

Auch Formulare sind manchmal Opfer von Spammern, die irgendwelche Daten auf Verdacht losschicken. Dabei ist die GET-Methode etwas mehr als die POST-Methode betroffen. Hilfreich kann es sein, einerseits typische Eingabefelder mit untypischen Namen zu versehen und dafür ein oder zwei Felder als Honigtöpfe aufzustellen - die bekommen dann einen typischen Namen wie 'email' oder 'phone', werden aber für den Anwender durch zusätzlichen Text als leerzulassen gekennzeichnet, bei Bedarf zudem per CSS vor den meisten Nutzern verborgen. Dumme Roboter neigen dazu, alle Felder auszufüllen und entlarven sich so. Akzeptiert man solche Eingaben aus Sicht des Roboters mit passender Rückmeldung wie für eine erfolgreiche Absendung, verwirft sie aber intern ohne zu speichern, so kann man solche Kandidaten recht zuverlässig aussortieren.

Insgesamt behandeln all diese Ansätze natürlich nicht die Wurzel des Problems, daß entsprechende Angaben zur Kontaktaufnahme mißbraucht werden, um Werbung oder Blödsinn zu verschicken, das ist mehr ein gesellschaftliches als technisches Problem, weswegen es wenig erfolgversprechend erscheint, da auf technischer Seite immer weiter aufzurüsten, statt das auf gesellschaftlicher Seite zu lösen.