Php-Formmailer (ohne Captcha) sicher gegen Header-Injection gestalten
Hallo,
brauche ein Grundgerüst für einen Formmailer ohne Captcha der sicher gegenüber Header-Injektion ist und brauche euren Rat.
Hab mir ein Grüst mit Selfhtml Muster zusammengebaut. Leicht modifiziert.
Mein Hauptziel zunächst ist lediglich keine Spamschleuder zu sein. alles weitere kommt später.
Variation gegenüber dem Original:
- Hab Code und html getrennt
- Hab alle Angaben für den Header (Absendername, Absenderadresse, Betreff und Zieladresse) fest eingegeben. (Ist ok für mich, es wird zunächst keine Antwortmail geschickt)
- Name, eMail etc. werden ausschließlich im Mailtext übermittelt.
- Bei der Übergabe des Mailtext habe ich zusätzlich Leerzeilen am Anfang eingefügt.
-> Grund: Weiß nicht ob das stimmt. Da ja Mailheader und Text durch eine Leerzeile getrennt werden, könnte ein Böser ja im Mailtext ein "Backspace" eingeben und hätte so die Möglichkeit weiteren Code in den Header zu integrieren. (Bin ich paranoid oder ist das möglich?)
Kontaktformular.htm
Mailer.php
Ich weiß, ich muß noch was einbauen um selber nicht zugespamt zu werden. Das mache ich wenn das Grundgerüst soweit bzgl. Spamschleuder stimmt.
Über weitere Tips bin ich dankbar!!
Gruß
Uwe
brauche ein Grundgerüst für einen Formmailer ohne Captcha der sicher gegenüber Header-Injektion ist und brauche euren Rat.
Hab mir ein Grüst mit Selfhtml Muster zusammengebaut. Leicht modifiziert.
Mein Hauptziel zunächst ist lediglich keine Spamschleuder zu sein. alles weitere kommt später.
Variation gegenüber dem Original:
- Hab Code und html getrennt
- Hab alle Angaben für den Header (Absendername, Absenderadresse, Betreff und Zieladresse) fest eingegeben. (Ist ok für mich, es wird zunächst keine Antwortmail geschickt)
- Name, eMail etc. werden ausschließlich im Mailtext übermittelt.
- Bei der Übergabe des Mailtext habe ich zusätzlich Leerzeilen am Anfang eingefügt.
-> Grund: Weiß nicht ob das stimmt. Da ja Mailheader und Text durch eine Leerzeile getrennt werden, könnte ein Böser ja im Mailtext ein "Backspace" eingeben und hätte so die Möglichkeit weiteren Code in den Header zu integrieren. (Bin ich paranoid oder ist das möglich?)
Frage: Ist der folgende Code gegen Header-Injektion sicher?
Kontaktformular.htm
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
<head>
<title>Einfacher PHP-Formmailer</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<h1>Beispielformular</h1>
<form action="mailer.php" method="post">
<!-- Hier die eigentlichen Formularfelder eintragen. Die folgenden sind Beispielangaben. -->
<dl>
<dt>Ihr Name:</dt>
<dd><input type="text" name="Name" /></dd>
<dt>Ihre E-Mail:</dt>
<dd><input type="text" name="E-Mail" /></dd>
<dt>Sie können:</dt>
<dd><input type="checkbox" name="kannwas" value="HTML" />HTML <input type="checkbox" name="kannwas" value="PHP" />PHP</dd>
<dt>Sie sind:</dt>
<dd><input type="radio" name="sexus" value="M" />Mann <input type="radio" name="sexus" value="Frau" />Frau</dd>
<dt>Sie mögen:</dt>
<dd><select name="Browser"><option value="Opera">Opera</option><option value="Mozilla">Mozilla</option></select></dd>
<dt>Nachricht:</dt>
<dd><textarea name="Nachricht" rows="3" cols="20"></textarea></dd>
</dl>
<!-- Ende der Beispielangaben -->
<p>
<input type="submit" value="Senden" />
<input type="reset" value="Zurücksetzen" />
</p>
</form>
</body>
</html>
Mailer.php
<?php
/**
* Konfiguration
*
* Das Skript bitte in UTF-8 abspeichern (ohne BOM).
*/
// Zu welcher Seite soll als "Danke-Seite" weitergeleitet werden?
// Wichtig: Sie muessen hier eine gueltige HTTP-Adresse angeben!
$urlDankeSeite = 'http://www.domain.de/danke.htm';
// Welche(s) Zeichen soll(en) zwischen dem Feldnamen und dem angegebenen Wert stehen?
$trenner = ":\t"; // Doppelpunkt + Tabulator
/**
* Ende Konfiguration
*/
if ($_SERVER['REQUEST_METHOD'] === "POST") {
$header = array();
// ++++ hier fest eintragen Absendername z.B Kontaktformular Absenderadresse z.B. Formmailer ++++++
$header = "From: ".mb_encode_mimeheader('Kontaktformular', "utf-8", "Q")." <".'Formmailer'.">";
$header = "MIME-Version: 1.0";
$header = "Content-type: text/plain; charset=utf-8";
$header = "Content-transfer-encoding: 8bit";
$mailtext = "";
foreach ($_POST as $name => $wert) {
if (is_array($wert)) {
foreach ($wert as $einzelwert) {
$mailtext .= $name.$trenner.$einzelwert."\n";
}
} else {
$mailtext .= $name.$trenner.$wert."\n";
}
}
$mailtext = "\n"."\n"."Sender IP".$trenner.$REMOTE_ADDR."\n".$mailtext;
mail(
// ++++ hier feste Zieladresse eintragen xxx@xxx.xx ++++
'name@domain.de',
// ++++ hier festen Betreff eingeben ++++++++++
mb_encode_mimeheader('Meldung vom Kontaktformular', "utf-8", "Q"),
$mailtext,
implode("\n", $header)
) or die("Die Mail konnte nicht versendet werden.");
header("Location: $urlDankeSeite");
exit;
}
header("Content-type: text/html; charset=utf-8");
Ich weiß, ich muß noch was einbauen um selber nicht zugespamt zu werden. Das mache ich wenn das Grundgerüst soweit bzgl. Spamschleuder stimmt.
Über weitere Tips bin ich dankbar!!
Gruß
Uwe
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 177556
Url: https://administrator.de/contentid/177556
Ausgedruckt am: 03.12.2024 um 17:12 Uhr
15 Kommentare
Neuester Kommentar
sieht gut aus ... finde nur das "Sie können: ... Sie sind: ... Sie mögen:" etwas eigenartig.
Die Umleitung auf die "Danke" Seite ist auch gut - das sollte ein "dauer reload" des Clients verhindern.
Was passiert eigentlich am Ende deines PHP Scriptes wenn $_SERVER['REQUEST_METHOD'] nicht "POST" ist ?
Wichtig ist, dass Du die E-Mail Adresse des Clients nicht einfach in dein E-Mail Header schreibst. Dadurch kann man noch am meisten Blödsinn anrichten.
Die Umleitung auf die "Danke" Seite ist auch gut - das sollte ein "dauer reload" des Clients verhindern.
Was passiert eigentlich am Ende deines PHP Scriptes wenn $_SERVER['REQUEST_METHOD'] nicht "POST" ist ?
Wichtig ist, dass Du die E-Mail Adresse des Clients nicht einfach in dein E-Mail Header schreibst. Dadurch kann man noch am meisten Blödsinn anrichten.
erhöht eine Gesamtphp (HTML und php in einem) die Manipulationsgefahr?
... es erhört die Gefahr einen Fehler zu übersehen und es mach das Script schwer zu warten, wenn eine Änderung gemacht werden soll.Was schlagt ihr vor, was soll ich machen, wenn "nicht POST"
... wenn nicht POST - dann hat jemand versucht dein PHP E-Mail Script manuell aufzurufen (auf unprofessionelle weise, denn es geht auch mit POST manuell aufzurufen) - Umleitung auf die StartseiteBeispiel für eine Prüfroutine eines hidden Feldes
... finde ich sinnlos, da jeder HTMLQuellcode lesen kann und wer echt böse drauf ist dem hindert das nicht.Insbesondere wie und an welcher Stelle baue ich das in meinen obigen Code ein?
wenn Du echt alles in eine Datei packen willst, dann mache die ganze Prüf-Logik und E-Mail senderei am Anfang deines ScriptesSchau mal nach Regulären Ausdrücken, um zB. die E-Mail Adressse zu prüfen, ebenso ist es nie falsch auch die Domain alleine mal abzufragen ob diese existiert.
hab da mal bissel gesucht (man findet massenhaft dazu): http://www.devshed.com/c/a/PHP/Email-Address-Verification-with-PHP/5/
Vermindern meine o.g. Primitiv-Strategien Header-Injection?
... ich glaube da bist sicher.Siehst du noch Ansatzpunkte für Spam-Schleuder, wenn ja welche?
nein - obwohl man sich ggf noch dem eigentlichen E-Mail Text annehmen sollte - spätestens wenn es darum geht den E-Mail Text wieder anzuzeigen.macht es Sinn die gesamte "mail" (Zeile 52) ... fest einzugeben?
das ist natürlich Dir überlassen - aber es ist nie falsch seinen Code gut lesbar / nachvollziehbar zu gestalten.Ab Zeile 89, wo ich ich ja die Werte im Formular z.T. zurückgebe, ist das besser mit "htmlentities" oder "htmlspecialchars"?
s.o. - beides ! , da man in den E-Mail auch so etwas wie:</textarea>
<script type="javascrip">
/* böses Javascript */
</script>
<textarea>
Frage 1
c) - ist nicht evtl. auch das Zeichen ' gefählich? Das wird durch die "html....( )" aber nicht maskiert.
d) - schieße ich mir mit "stripslashes" evtl. ein Eigentor?
das könnte insbesondere bei " passierend) - schieße ich mir mit "stripslashes" evtl. ein Eigentor?
addslashes( htmlentities($_POST['Name']) )
// oder auch
addslashes( htmlentities( strip_tags($_POST['Name']) ) )
Frage 2
nein - und ja wenn man Befehle wie exec oder die Backticks nutzt ( Shell aufrufe )Frage 3
die super-globalen $_POST, $_GET ... sind je nach Umgebung immer gesetzt, auch wenn diese leer sind.Wenn Du alles was über $_GET kommt loggen willst, wird das hässlich - denke doch mal nach was passiert wenn Google deine Webseite indizieren will.
Grundsätzlich gilt: "Daten welche vom Client gesendet werden darf man nicht vertrauen" .. das gilt auch für die $_SERVER Variable, zB mit dem Referer oder Agent
Frage 4
das sind dann richtige Bugs im Server und/oder der Script Sprache - und ja es gibt so paar Tricks mit speziellen Steuerzeichen.4.
allg. brauchst Du dir keine sorgen machen über den Inhalt dieser Variablen, sollte jemand versuchen dir 10 GByte an POST Daten zu senden, dann wird er wohl entweder schon dein Server beim Empfang der Daten lahmlegen (was nicht passieren dürfte) oder er bekommt einen Timeout Fehler vom Server und dein Script wird gar nicht erst ausgeführt.3.
s. 4. - solange Du nicht auf den Wert in GET zugreifen musst, kann da drin stehen was will, dass braucht dich nicht zu kümmern2.
... kann ich Dir keine Antwort geben (Frage fehlt)1.
Die ' werden wohl nicht ersetzt, weil diese im HTML Code kein Problem sind, wenn man sich an den Standard hält. Die " werden natürlich ersetzt, weil diese sonnst deine HTML-Attribute (name="wert") stören würden.schau mal nach: 'magic_quotes_gpc'
in den meisten fällen reicht:
nl2br( htmlentities( ) ); // für HTML Inline Code
htmlentities( ); // für HTML Attribut Inhalt
Frage 1
Wenn die Daten in $_WASAUCHIMMER gespeichert sind, wurden diese natürlich bereits vom Server empfangen und liegen im Speicher. Nur wenn Du Probleme hast mit deinem Speicher Verbauch wäre das sinnvoll.Frage 2
2a
Das ist völlig Egal - spätestens beim mail Funktionsaufruf werden die Parameter zu einer Variablen. Es ist durchaus sinnvoll, zB könnte man solche Festen Zeichenketten auch auslagern in ini Dateien oder sogar in po oder mo Dateien zur Übersetzung.2a
2b
Nein - das wäre schlimm, wenn man nicht mal seinen eigenen Variablen trauen könnte. Einzige Möglichkeit ist, wenn durch die Session Variablen gesetzt/gespeichert werden, aber diese können auch nur schwer vom Client manipuliert werden.Also Danke nochmal für deine weiterhelfenden, konkreten Antworten.
immer gernemachen die das um im "Ranking" hochzusteigen?
na macht doch jeder - und damit das nicht so aussieht als ob ich mit diesem Kommentar auch NUR einen Punkt erhalten will ...ob die empfangene Anfrage vom meinem eigenem Formular stammt
... gebe ich dir mal einen Link mit: http://php.net/manual/de/reserved.variables.server.php ... und den Hinweis: HTTP_REFERER (Wichtig: Beschreibung lesen - erst recht den letzten Satz)