Seitenanfang

Perl Taint mode: Datenwäsche

Im ersten Teil habe ich den Taint mode vorgestellt und gezeigt, wie gefährlich unbekannte Daten sein können. Jetzt geht es um die nicht minder wichtige Frage, wie man sich diese Daten trotzdem nutzbar machen kann. Das Ziel einer jeden (Web-)Anwendung sollte es sein, mit legitimen Eingaben problemlos und effizient umzugehen ohne dabei die Sicherheit gegenüber Betrugsversuchen leiden zu lassen.

secure_perl.jpgIch arbeite hauptberuflich an und mit Webanwendungen, die frei im Internet erreichbar sind. Jeden Tag werden sie von vielen Menschen genutzt und fast alle wollen nichts weiter, als sie ordnungsgemäß zu benutzen. Trotzdem finden sich jeden Tag Zugriffe in den Logdateien, die nichts Gutes im Sinn hatten. Simple SQL-Injections gehören ebenso zum Standard wie manipulierte Links oder simple Betrugsversuche, aber auch unerklärliche Formulareingaben, bei denen sich die Intention des Absenders nicht erraten lässt, gehören zum Standard.

Im einfachsten Fall sind es Menschen, die von Ihren Eltern den Vornamen(!) "Max Martin Müller-Mustermann, Beispielstraße 5, 12345 Testort/Sonstwo" bekommen haben. Natürlich ist das Beispiel frei erfunden, aber ähnliche Eingaben finden sich nicht selten im Feld "Vorname". Eingabeprüfungen per JavaScript helfen nur sehr bedingt gegen so etwas, denn es lässt sich einfach abschalten oder umgehen.

Gehen wir einmal davon aus, dass das Avatarbild dieser Person als "vorname.jpg" gespeichert werden soll (wie gut diese Lösung ist, steht auf einem anderen Blatt). Um Dateinamen mit Leerzeichen zu vermeiden, wird jedes Leerzeichen durch einen Unterstrich ersetzt:

$vorname =~ s/ /_/g;
open my $fh,'>',$vorname.'.jpg';

Ohne Taint mode würde jetzt die Datei Max_Martin_Müller-Mustermann,_Beispielstraße_5,_12345_Testort/Sonstwo.jpg erstellt werden - oder auch nicht, denn der Schrägstrich im Ortsnamen ist ein in Dateinamen nicht erlaubtes Zeichen und führt zu einem Fehler. Das nächste Problem tritt auf, wenn dieser 72 Zeichen lange Vorname in einem 30 Zeichen großen VARCHAR einer Datenbank-Tabelle gespeichert werden soll.

Dieses Beispiel mag nicht sehr schlimm aussehen, es verursacht im besten Fall nur vermeidbaren Supportaufwand, aber es soll stellvertretend für alle anderen denkbaren Fälle stehen.

Gültige Vornamen sollten in diesem Beispiel möglichst nur Buchstaben, Zahlen, Bindestriche, Leerzeichen und Punkte enthalten. Sie müssen mindestens 2 und höchstens 30 Zeichen lang sein. Eine RegEx dafür ist sehr einfach:

$vorname =~ /^[a-zA-Z0-9\-\. ]{2,30}$/;

Das obige Negativbeispiel ist damit ausgeschlossen: Es enthält nicht zugelassene Zeichen und ist viel zu lang. Mit dieser simplen Prüfung ist das Feld Vorname aber schon beinahe bereinigt, dazu fehlt nur noch eine Klammer:

$vorname =~ /^([a-zA-Z0-9\-\. ]{2,30})$/ or die "Nicht erlaubter Vorname";
my $vorname_sicher = $1;
$vorname_sicher =~ s/ /_/g;
open my $fh,'>',$vorname_sicher.'.jpg';

Mit Hilfe der zusätzlichen Klammer wird der Wert - sofern er gültig ist - als $1 bereitgestellt. Perl geht davon aus, dass sich der Entwickler bei der Überprüfung der Daten mit einer RegEx ernsthafte Gedanken gemacht hat und das Ergebnis sicher ist - und markiert deren Ergebnis nicht als tainted oder vergiftet.

Natürlich schützt so eine Prüfung nicht vor allen möglichen Problemen: In diesem Fall wäre die Zeichenkette ".." ebenfalls ein gültiger Wert, der im Dateisystem potentiell Schaden anrichten könnte. Ein andere beliebter Fehler ist es, unerwünschte Zeichen auszuschließen, anstatt erwünschte zu erlauben - dabei besteht aber immer ein großes Risiko, dass man ein schädliches Zeichen übersieht.

 

Noch keine Kommentare. Schreib was dazu

Schreib was dazu

Die folgenden HTML-Tags sind erlaubt:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>