10x bewertet

Filterfunktion gegen Injections

von SmaX  |  26.12.2009 um 18:29 h
Skripte
Typ: Skripte
Stufe:Nur für Fortgeschrittene
Hey!

Ich möchte euch in diesem Tutorial eine Filter Funktion vorstellen, die euch bzw. eure Anwendung größtenteils, wenn ihr die Funktion natürlich auch anwendet vor Mysql Injections und anderen Angriffen schützen soll.

Ich erkläre nicht alles so ausführlich weil das dann den Rahmen fast sprengen würde.

Aber fangen wir mal an mit der Hauptfunktion, die wir dann am Ende aufrufen und die unsere anderen Funktionen aufruft. Sie heißt msql(), ich habe sie so benannt weil ich fast ausschließlich mysql befehle damit absichere.


<?//HAUPTFILTER FUNKTION
function msql($string$art "string") {

if(
$art == "string") { //Wenn nur string erlaubt (standart)
$string mysql_filter($string); //Mysql parameter entfernen
$string strip_tags($string); //HTML rausfiltern
$string htmlentities($stringENT_QUOTES); // Apostrophe in html
umwandeln  
$string 
wordwrap($string65"<br/>"true);

}elseif(
$art "html") { // Wenn html erlaubt
$string mysql_filter($string); //Mysql parameter entfernen
$string filter_html($text); //unerlaubte html tags filtern
$string htmlentities($stringENT_QUOTES); // Apostrophe in html
umwandeln 
}

return 
$string;
}
?>



Hier werden verschiedene Funktionen die schon von PHP vorgegeben sind, und noch zwei weitere Funktionen aufgerufen.

Aber als erstes wird mal entschieden, ob es sich um einen normalen String oder um eine HTML Eingabe handelt, das könnt ihr selbst bestimmen, aber dazu später mehr. Als Standart ist ein normaler String angegeben, also z. B. eine Profileingabe oder eine einfache Nachricht in der KEINE HTML tags erlaubt sind.

Wenn es sich um einen string handelt, bzw. ein string erwartet wird, dann werden die Funktionen mysql_filter(), strip_tags() und htmlspecialchars() aufgerufen. Die erste Funktion filtert alle mysql Parameter heraus, z. B. OR oder WHERE, dazu aber später mehr. Die Funktion strip_tags entfernt alle PHP und HTML tags. Die letzte Funktion htmlspecialchars wandelt Apostrophen (",′) in HTML um also z. B. in " und mit diesem HTML-tag kann man keine Injection machen, was ja für uns dann ein vorteil sein wird.

Wenn es sich aber um eine HTML Eingabe handelt, also z. B. mithilfe eines HTML Webeditors, dann sollen ja nicht alle HTML Befehle entfernt werden sondern nur die Apostrophe unschädlich gemacht werden, unerwünschte Tags rausgefiltert werden und
Mysql-Parameter entfernt werden. Dies geschieht durch mysql_filter(), filter_html() und htmlentities(). Dazu gleich mehr.

Das war die erste Funktion, als nächstes beschreibe ich die Funktion mysql_filter(), diese Funktion soll alle Mysql Parameter herausfiltern (OR, WHERE) dies soll auch eine Mysql Injection verhindern.

Hier die Funktion:

<? 

//Mysql Parameter werden herausgefiltert
function mysql_filter($text) {

$text str_replace("OR"""$text);
$text str_replace("or"""$text);
$text str_replace("AND"""$text);
$text str_replace("and"""$text);
$text str_replace("WHERE"""$text);
$text str_replace("where"""$text);
$text str_replace("LIKE"""$text);
$text str_replace("like"""$text);

return 
$text;
}

?>



Ich habe mit Absicht nicht so viel kommentiert, weil es sich immer um die gleiche Funktion handelt, nämlich str_replace(), diese Funktion Filtert die forderen Ausdrücke heraus, und ersetzt sich durch die hinteren in diesem Fall nix, also entfernt sie.

Hier noch die letzte benötigte Funktion nämlich filter_html():


<? 
function filter_html($text) { // Text umwandeln

//Php tags entfernen
$text str_replace("<?"""$text);
$text str_replace("?>"""$text);
$text str_replace("<?php"""$text);
$text str_replace("php?>"""$text);

//Bestimmte HTML tags entfernen
$text str_replace("<script"""$text);
$text str_replace("</script>"""$text);
$text str_replace("<title>"""$text);
$text str_replace("</title>"""$text);
$text str_replace("<style"""$text);
$text str_replace("</style>"""$text);
$text str_replace("<frameset"""$text);
$text str_replace("<frame"""$text);
$text str_replace("</frameset>"""$text);
$text str_replace("</frame>"""$text);
$text str_replace("<iframe"""$text);
$text str_replace("</iframe>"""$text);

return 
$text;

}
?>



Hier werden alle HTML - Tags gefiltert die unerwünscht sind. Diese Liste kann man noch ergänzen. Hier kommt auch wieder die Funktion str_replace vor: Der fordere Ausdruck wird durch den hinteren ersetzt. In diesem Fall komplett entfernt. Als letzter Parameter muss wieder die Eingabevariable eingesetzt werden. In dieser Funktion filter_html() kommt auch noch eine andere Praktische Funktion zum Einsatz: wordwrap(). Diese Funktion trennt zulange Ausdrücke durch <br/> also einen Zeilenumbruch. So passiert es nicht, dass eine Usereingabe über den Inhaltsbereich hinausragt. Die Funktion ist auf 65 Zeichen eingestellt, das könnt ihr auch beliebig ändern.

Am wichtigsten ist natürlich bei allen drei Funktionen das der Endwert also der gefilterte String wieder zurückgegeben wird, das geschieht durch return $VARIABLE; Natürlich wird VARIABLE durch die entsprechende Variable ersetzt. Die drei Funktionen könnt ihr jetzt in eure functions.inc.php einfügen. Hier nochmal der ganze Code:


<? 
//HAUPTFILTER FUNKTION
function msql($string$art "string") {

if(
$art == "string") { //Wenn nur string erlaubt (standart)
$string mysql_filter($string); //Mysql parameter entfernen
$string strip_tags($string); //HTML rausfiltern
$string htmlentities($stringENT_QUOTES); // Apostrophe in html
umwandeln -> 
}elseif(
$art "html") { // Wenn html erlaubt
$string mysql_filter($string); //Mysql parameter entfernen
$string filter_html($text); //unerlaubte html tags filtern
$string htmlentities($stringENT_QUOTES); // Apostrophe in html
umwandeln -> 
}

return 
$string;
}


//Mysql Parameter werden herausgefiltert
function mysql_filter($text) {

$text str_replace("OR"""$text);
$text str_replace("or"""$text);
$text str_replace("AND"""$text);
$text str_replace("and"""$text);
$text str_replace("WHERE"""$text);
$text str_replace("where"""$text);
$text str_replace("LIKE"""$text);
$text str_replace("like"""$text);

return 
$text;
}

function 
filter_html($text) { // Text umwandeln

//Php tags entfernen
$text str_replace("<?"""$text);
$text str_replace("?>"""$text);
$text str_replace("<?php"""$text);
$text str_replace("php?>"""$text);

//Bestimmte HTML tags entfernen
$text str_replace("<script"""$text);
$text str_replace("</script>"""$text);
$text str_replace("<title>"""$text);
$text str_replace("</title>"""$text);
$text str_replace("<style"""$text);
$text str_replace("</style>"""$text);
$text str_replace("<frameset"""$text);
$text str_replace("<frame"""$text);
$text str_replace("</frameset>"""$text);
$text str_replace("</frame>"""$text);
$text str_replace("<iframe"""$text);
$text str_replace("</iframe>"""$text);

$text wordwrap($text65"<br/>"true);

return 
$text;

}

?>



Ich zeige euch jetzt noch wie ihr diese Funktion auch verwendet. Nehmen wir mal an Ihr wollt ein kleines Formular erstellen, welches Eingaben entgegennimmt und dann in eure Datenbank einfügt. Ich lasse jetzt der Übersicht halber, das IF usw. weg und konzentriere mich nur auf den mysql-Befehl:


<? 

$insert 
mysql_query("INSERT INTO formulartabelle (name, email)
VALUES ('"
.msql($_REQUEST["name"])."', '".msql($_REQUEST["email"])."')
"
);

?>



Es werden jetzt name und email entgegengenommen und gefiltert. Es werden also normale string Eingaben erwartet. Wenn ihr jetzt HTML Eingaben erwartet, dann lautet das Codebeispiel so:


<? 

$insert 
mysql_query("INSERT INTO formulartabelle (name, email)
VALUES ('"
.msql($_REQUEST["name"], html)."',
'"
.msql($_REQUEST["email"], html)."') ");

?>



Wenn ihr dieses Codebeispiel verwendet, dann können die User ihren Namen und ihre Emailadresse beliebig formatieren:

<b>SmaX</b>

usw.
Es ist euch überlassen, ob html oder string, wie schon erwähnt, standartmäßig ist string aktiviert.


Ich hoffe euch gefällt mein Tutorial, und ihr verwendet den Code vielleicht auch.


Lob, Kritik, Anregungen, Fragen sind natürlich gerne erwünscht.



MfG SmaX

EDIT: Habe htmlspecialchars() durch htmlentities() ersetzt, es sind eigendlich beides die gleichen Funktionen nur das htmlentities noch effektiver arbeitet und wirklich alle Tags filtert.



8 Kommentare




SmaX

Immer des gleiche: Wenn einem das Script nicht gefällt, dann soll man nicht nur 3 Punkte geben sondern auch was dazuschreiben! Derjenige is echt so feige.. warscheinlich Angst haben das er dann nen Kommentar zurückbekommt. Ich finde des so mieß, ich mach des schließlich bei anderen Tutorials auch nicht!
am 26.12.2009 um 19:40 Uhr


Lile

Sehr gut erklärtes Tutorial, ausführlich und dennoch dünn und knapp gehalten, bei mir hat alles bestens funktioniert! Super Sache ;) 6*
am 26.12.2009 um 20:00 Uhr


Ich finde das Tutorial sehr hilfreich
habe dir 6 punkte gegeben...

weiter so Smilie
am 26.12.2009 um 20:59 Uhr


Isa_G

Wichtiges Thema, gut beschrieben und nützlich.
Ich sichere momentan mein ACP und da kommt es eigentlich recht günstig, ich denke ich werde deine Variante mal anwenden. :)
Ab und zu gibt es noch eine Grammatikfehler, über die man aber hinweg sehen kann.
Ich schwanke noch zwischen 5-6 Punkten.
am 27.12.2009 um 12:50 Uhr


SmaX

Danke an Euch!

Ich bin eben auch grad dabei ein CMS zu schreiben und muss das so sicher wie Möglich machen. Darum habe ich mir gedacht, komm die bei Giatu brauchen soetwas bestimmt auch. Smilie
am 29.12.2009 um 15:23 Uhr


smoothie

was ist ein CMS ?
Und wofor schützt dieser Filter bzw. was schützt er?Die datenbank oder den ganzen server :)
am 07.01.2010 um 21:12 Uhr


werock2040

Ein CMS ist ein ContentManagemantSystem, wo man Daten online verwalten kann,mal so grob erklärt. Aus Delites Tutorials könnte man auch ein CMS zusammenbasteln. Da die Scripts aber nicht sicher ist, sollte dieses Tutorial von SMAX die Scripts vor möglichen Attacken schützen,denke ich mal Smilie.
am 07.01.2010 um 21:48 Uhr


SmaX

Hey,

ja genau richtig erkannt! xD
am 08.01.2010 um 16:12 Uhr