Sicherheitslücken im Mailscript

Seven Secrets

Erfahrenes Mitglied
Hallo,

Ich habe ein Mailformular:

PHP:
<?php
$emailadresse="mail@domain.de";

if ($submit)
{
 if ($betreff=="" || $lname=="" || $strasse=="" || $ort=="" || $plz=="" || $telefon=="" || $email=="" || $kommentar=="" || $checkbox=="")
 {
 echo "
 <table width=\"90%\" border=\"0\" align=\"center\" cellpadding=\"0\" cellspacing=\"0\">
  <tr>
    <td></td>
  </tr>
  <tr>
    <td height=\"23\"><font face=\"Verdana,Arial,Helvetica\" size=\"2\">&nbsp;</p></td>
  </tr>
  <tr>
    <td></td>
  </tr>
  <tr>
    <td></td>
  </tr>
  <tr>
    <td><strong><div class=\"inhalt\"><font color=\"#FF0000\">Um Ihren Anfrage
      korrekt zu bearbeiten, möchten wir Sie bitten, das Formular vollständig
      auszufüllen. Nur so ist eine schnelle und zuverlässige Bearbeitung Ihrer
      Anfrage gewährleistet.</font></div></strong></td>
  </tr>
  <tr>
    <td><br><br></td>
  </tr>
  <tr>
    <td><div align=\"right\" class=\"inhalt\"><a href=\"javascript:history.back()\">zurück</a></div></td>
  </tr>
</table>
</td>
          <td width=\"3\" background=\"grafics/rborder.jpg\" bgcolor=\"#FFFFFF\"></td>
        </tr>
        <tr> 
          <td colspan=\"5\"><img src=\"grafics/bborder.jpg\" width=\"780\" height=\"20\"></td>
        </tr>
      </table>
    </td>
  </tr>
</table>
</body>
</html>
";
exit();
}
else
{
 echo "
 <table width=\"90%\" border=\"0\" align=\"center\" cellpadding=\"0\" cellspacing=\"0\">
  <tr>
    <td></td>
  </tr>
  <tr>
    <td height=\"10\">&nbsp;</td>
  </tr>
  <tr>
    <td></td>
  </tr>
  <tr>
    <td></td>
  </tr>
  <tr>
    <td><div align=\"justify\" class=\"inhalt\"><b>Vielen
        Dank für Ihre Anfrage wir werden sie so schnell wie m&ouml;glich bearbeiten und uns mit Ihnen in Verbindung setzen.</b></div></td>
  </tr>
</table>
          <td width=\"3\" background=\"grafics/rborder.jpg\" bgcolor=\"#FFFFFF\"></td>
        </tr>
        <tr> 
          <td colspan=\"5\"><img src=\"grafics/bborder.jpg\" width=\"780\" height=\"20\"></td>
        </tr>
      </table>
    </td>
  </tr>
</table>
</body>
</html>
";
 mail("$emailadresse","$betreff", "Betreff:\t $betreff\nVorname:\t $fname\nNachname:\t $lname\n\nStrasse:\t $strasse\nOrt:\t\t $plz $ort\n\nTelefon:\t $telefon\nE-Mail:\t $email\nKommentar:\t $kommentar\n\n\n$REMOTE_ADDR\n$REMOTE_HOST\n$HTTP_USER_AGENT","From: $email");
 exit();
 }
}
?>
<table width="97%" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
   <td> <div class="inhalt"><strong><br>Kontakt<br><br></strong></div>
	 <form action="<?php echo "index.php?inhalt=contact"; ?>" method="post" name="formmail">	
        <table width="400" border="0" align="center" cellpadding="1" cellspacing="1">
          <tr> 
            <td width="156" height="25" valign="middle"> <div class="inhalt">Vorname</div></td>
            <td width="258"><input name="fname" type="text" id="fname" size="40" maxlength="50">
            </td>
          </tr>
          <tr> 
            <td width="156" height="25" valign="middle"> <div class="inhalt">Nachname:</div></td>
            <td>  
              <input name="lname" type="text" id="lname" size="40" maxlength="50">
              </td>
          </tr>
          <tr> 
            <td width="156" height="25" valign="middle"> <div class="inhalt">Strasse:</div></td>
            <td> 
              <input name="strasse" type="text" id="strasse" size="40" maxlength="50">
              </td>
          </tr>
          <tr> 
            <td width="156" height="25" valign="middle"> <div class="inhalt">Ort:</div></td>
            <td> 
              <input name="ort" type="text" id="ort" size="40" maxlength="50">
              </td>
          </tr>
          <tr> 
            <td width="156" height="25" valign="middle"> <div class="inhalt">Postleitzahl:</div></td>
            <td> 
              <input name="plz" type="text" id="plz" size="40" maxlength="50">
              </td>
          </tr>
          <tr> 
            <td height="25" valign="middle"> <div class="inhalt">Telefon:</div></td>
            <td> 
              <input name="telefon" type="text" id="telefon" size="40" maxlength="50">
              </td>
          </tr>
          <tr> 
            <td width="156" height="25" valign="middle"> <div class="inhalt">E-Mail:</div></td>
            <td>  
              <input type="text" name="email" id="mail" maxlength="50" size="40">
              </td>
          </tr>
          <tr> 
            <td width="156" height="25" valign="middle"> <div class="inhalt">Betreff:</div></td>
            <td>  
              <input type="text" name="betreff" id="betreff" maxlength="50" size="40">
              </td>
          </tr>
          <tr> 
            <td width="156" valign="top"> <div class="inhalt">Nachricht:</div></td>
            <td>  
              <textarea cols="30" rows="4" name="kommentar"></textarea>
              </td>
          </tr>
          <tr> 
            <td width="156" align="center" valign="middle"> <div align="center" class="inhalt">
                <input type="checkbox" name="checkbox" value="akzeptiert">
                </div></div></td>
            <td><div class="inhalt"><font size="-4">Ich 
              bin mit dem Senden meiner Daten einverstanden. <br>
              (Anklicken, da sonst nicht gesendet wird!)</font></div></td>
          </tr>
          <tr> 
            <td width="156" valign="top">&nbsp;</td>
            <td>&nbsp;</td>
          </tr>
          <tr> 
            <td width="156"> <p> </p></td>
            <td height="25"> <div class="inhalt"> 
              <input type="Submit" name="submit" value="Senden">
              <input type="Reset" name="reset" value=" Reset ">
              </div></td>
          </tr>
        </table>
</form>
</td>
</tr>
</table>

Dieses soll laut Schlund und Partner zum versenden von Spam-Mails genutzt worden sein und Sicheheritslücken aufweisen. Nun habe ich mich schon drei stunden zu tode gegooglet um eine Lösung oder einen Ansatz zu finden, doch leider finde ich nichts passendes dazu.

Welche Sicherheitslücke wird gemeint udn wie kann man diese schließen?
 
Ich tippe mal, dass das Problem die Variable $email sein wird.
Diese nutzt Du um zusaetzliche Header anzugeben, was dazu fuehrt, dass jeder beliebige Header anfuegen kann, z.B. weitere Empfaenger.

Weiterhin verlaesst sich Dein Script auf register_globals=on, was hier zwar eher nebensaechlich ist, aber Dir in Zukunft evtl. Schwierigkeiten bereiten koennte wenn Du mal den Hoster wechselt oder Dein aktueller Hoster diese Einstellung auf off setzt.
 
Okay, das ist ne Richtung mit der ich was anfangen kann! Jetzt noch nen Tip wohingehend ich das ändern soltle und ich bin der glücklichste Mensch auf der Welt!
 
Du musst die Variable vor dem Versand pruefen. Wichtig ist, dass keine Zeilenumbrueche vorkommen duerfen, denn diese trennen die einzelnen Header-Felder von einander.
 
Ich habe dieses Mailformular mal bei Heise entdeckt... Da hat sich auch jemand Gedanken um die Spam-Anfälligkeit gemacht und folgendes fabriziert:

PHP:
<html>
 <head>
  <title>Mailformular</title>
   </head>
 <body>
 
 
 
  <?php
 //Gib Fehler und Warnungen aus
 error_reporting(E_ALL);
 //Deutschsprachige Umgebung, damit die
 //regulären Ausdrücke auch Umlaute etc. erkennen
 setlocale(LC_ALL, 'de_DE');
 //Erzeuge einen zufällig aussehenden Zugangscode aus dem Datum ...
 $code = chr((date("y") + 7) % 10 + date("m") + 68 + (date("m") % 2) * 32) . chr((date("d") + (date("d") %2)) / 2 + 66 + (37 * (date("d") %2)));
 //... den der Anwender mittels verborgenem Eingabefeld übergibt.
 //So lässt sich das Gros der skriptgesteuerten Angriffe von
 //vornherein abblocken.
 //Wurde das Formular abgeschickt?
 //Falls ja: Daten prüfen und versenden
 if(isset($_POST['los'])) {
  if(!isset($_POST['code']) || $_POST['code'] != $code) die('Mailcode fehlt!');
  //Liste der zu überprüfenden Formularfelder:
  //'absender' muss genau eine Mailadresse sein,
  //'betreff' uch,
  //'text' muss zehn Zeicheist ein mindestens drei Zeichen langer Text ohne Umbrn lang sein.
  $pruefung = array(
  'absender' => '/^[\w.+-]{2,64}\@[\w.-]{2,255}\.[a-z]{2,6}$/',
   //prüft auf gültige E-Mail-Adresse nach RFC 2822,
   //erlaubt auch ungewöhnliche Adressen wie "{@heise.de";
   //strengere Prüfung (erfordert z.B. mindestens 2 Zeichen vor @
   //und im Domainnamen, schließt ungewöhnliche Adressen aus):
   //'absender' => '/^[\w.+-]{2,64}\@[\w.-]{2,255}\.[a-z]{2,6}$/',
   //'betreff' => '/^[[:print:]]{3,}$/',
   //restriktivere Variante:
   'betreff' => '/^[[:alnum:]\s\?.!,;:\(\)\/\"-]{3,}$/',
   'text' => '/^[[:print:][:space:]]{10,}$/'
  );
  //Durchlaufe alle Formulardaten:
  foreach($_POST as $parameter => $wert) {
   //Formularfelder, die in $pruefung stehen,
   //müssen in die oben definierten Muster passen
   if(isset($pruefung[$parameter])) {
    if(!preg_match($pruefung[$parameter], $wert)) die('<a href="mail.php">Zurück</a><br><br>' . 'Probleme mit Feld: ' . $parameter . ': ' . $wert);
   } else {
    //Der Rest wird weggeworfen.
    unset($_POST[$parameter]);
   }
  }
  //Prüfe, ob die Absenderadresse einem gültigen MX-Host angehört
  //Zu jeder Domain in einer Mailadresse (nach dem @-Zeichen)
  //sollte ein Mail Exchange Resource Record (MX-RR) im Domain Name
  //System (DNS) eingetragen sein. Die MX-Hosts versenden die E-Mail
  //per SMTP. getmxrr() schreibt MX-Hosts in das Array $mxhosts
  //ACHTUNG: Dieser Befehl ist nur auf Unix-Maschinen implementiert,
  //unter anderen Betriebssystemen ist die Zeile zu streichen!
  //Außerdem scheint getmxrr() Probleme mit Umlautdomains zu haben.
  if(!getmxrr(substr(strstr($_POST['absender'], '@'), 1), $mxhosts)) die("Die angegebene E-Mail-Adresse <b><i> " . $_POST['absender'] . " </i></b>gibt es nicht !");
  //Die Formulardaten sind ok -- der Mailversand wird vorbereitet:
  //mail() erwartet Empfänger, Betreff, Text und weitere Kopfdaten
  if(mail('etwas@domain.de', $_POST['betreff'], $_POST['text'], "From:" . $_POST['absender'])) {
   //Es hat geklappt: Bestätigung ausgeben
   echo "<p>Ihre Mail (E-Mail-Adresse: <b>" . $_POST['absender'] . " </b>) wurde erfolgreich gesendet!</p>";
  } else {
   //Irgendwas ist schiefgelaufen :-(
   echo "<p>Fehler!!</p>";
  }
 } else {
 //Es wurden keine Formulardaten übergeben ->
 //Gib einen HTML-Block mit dem Formular aus.
?>

   <form method="post" action="">
   <table>
    <tbody>
     <tr>
      <td>
       <label for="absender"><b>Absender:</b></label>
       <i></i> </td>
      <td>
       <input name="absender" id="absender" size="40"/>      </td>
     </tr>
     <tr>
      <td>
       <label for="betreff"><b>Betreff:</b></label>
       <i></i>      </td>
      <td>
       <input name="betreff" id="betreff" size="40"/>      </td>
     </tr>
     <tr>
      <td>
       <label for="text"><strong>Text:</strong></label>
       <i></i>      </td>
      <td>
        <input name="text" type="text" id="text" value="
       " size="40" />
       <input type="hidden" id="code" name="code" value="<?php echo($code); ?>"/>      </td>
     </tr>
          <tr>
      <td>
	  </td>
      <td>
       <input type="submit" name="los" value="Abschicken!"/>      </td>
     </tr>
    </tbody>
   </table>
  </form>
<?php
 //Schließt die if-else-Schleife
 }
?>
 </body>
</html>

Wie sicher das allerdings tatsächlich ist kann ich leider nicht beurteilen... ;-)

Tetsuo
 
Jetzt verstehe ich das! Alles klar! Aber Moment!

PHP:
mail("$emailadresse","$betreff", "Betreff:\t $betreff\nVorname:\t $fname\nNachname:\t $lname\n\nStrasse:\t $strasse\nOrt:\t\t $plz $ort\n\nTelefon:\t $telefon\nE-Mail:\t $email\nKommentar:\t $kommentar\n\n\n$REMOTE_ADDR\n$REMOTE_HOST\n$HTTP_USER_AGENT","From: $email");

Das ist die Funktion die sendet, nicht wahr! Gut! die Schlüsselt sich ja nun so auf: mail($empfaenger, $betreff, $text, $from);

Soll ich da nur den Empfängerteil prüfen lassen?
 
PHP:
if (strpos($email,"\n") || strpos($email,"\r"))	die("Fehlermeldung: ...");


Dadurch wird sichergestellt, das nur ein Absender angegeben ist.


Edit: Anführungszeichen korrigiert.
 
Zuletzt bearbeitet:
Zurück