|
Grundüberlegung bei der CGI-Programmierung sollte immer die Annahme sein, dass man niemals dem Browser und/oder dem daran hantierenden User trauen sollte. Aus diesem Grund sollte man die Verwendung der Shell vermeiden und zusätzlich den Taint-Modus aktivieren. Dies sollte in Einklang mit einem Systemdesign erfolgen, welches so gestaltet sein sollte, dass ein Eindringling (Cracker) keinen Vorteil aus einem Einbruch gewinnt. Er soll höchstens Spuren hinterlassen, die zu seiner Überführung dienen. WWW-Server werden häufig als Angriffspunkte gewählt, weil sie den exponiertesten Punkt einer Unternehmung (buchstäblich im Wohnzimmer des Kunden) bilden. Auch sind die Komponenten schnell ausspioniert und Schwächen bekannt. Eigene Programme sollten deshalb aus diesen Fehlern lernen und die Sicherheitsmöglichkeiten des darunterliegenden Softwarestacks auch nutzen. Wichtige Daten sollten aus dieser latenten Gefahr nicht physikalisch auf demselben Rechner wie der Web-Server gespeichert werden. Zudem ist in der Netzkonfiguration darauf zu achten, dem Web-Server wenig "Vertrauen" entgegenzubringen. Ein Eindringling wird sich zuerst den Rechner mit dem Web-Server unter seine Kontrolle bringen, und von dort aus seine Angriffe auf das Inhouse-Netz starten. Grundsätzlich gilt bei jeder Anwendung, die für andere mit eigenen Privilegien läuft, die Beachtung strenger Sicherheitsrichtlinien. Das betrifft insbesondere ausführbare Dateien, die mit einem s-bit ausgestattet sind (das heißt sie laufen unter UNIX mit anderen Privilegien als denen des aufrufenden Benutzers), und insbesonderem Maße für Internet-Anwendungen, da sie für jeden Informationsanbieter einen möglichen Angriffspunkt darstellen. Gründe zur Nutzung des Taint-Modus Neben den üblichen Techniken zur Vermeidung von Programmierfehlern (``-w'' auf der Kommandozeile und use strict), gibt es hierfür noch eine weitere wertvolle Unterstützung: den ``taint mode'', der entweder automatisch eingeschaltet wird (bei Skripten mit s-bit) oder auch explizit gewünscht werden kann (Option ``-T'' auf der Kommandozeile). Der Taint-Modus von Perl bewirkt von sich aus erst einmal nichts Magisches, er achtet nur wie ein Coach darüber , dass der Programmierer keine großen Löcher in den sicheren Schutz des Systems reisst. Diese Aufgabe könnte der Programmierer auch selbst übernehmen, aber dieses eingebaute Feature kostet keine Mark mehr. Deshalb kann man auch die rhetorische Frage stellen "Warum sollte der Taint-Modus nicht genutzt werden ?" Viele CGI-Entwickler scheuen den Taint-Modus, jeder aus eigenen Motiven, z.B. weil er als zu kompliziert erscheint, zu schwer zu durchschauen oder er legt dem Programmierer zu viele Ketten an. Nun, nicht viel ist umsonst, aber der Taint-Modus schon. Diese Urteile kommen oft aus einem Unverständnis über den Taint-Modus heraus. Es ist halt einfacher, die mahnende Instanz einfach auszustellen, anstatt lernen zu wollen wie die von Perl aufgedeckten Sicherheitslücken gestopft werden können. Performance wird oft als Argument genannt, den Taint-Modus auszustellen, aber Untersuchungen haben gezeigt, dass keine nennenswerten Einbussen in der Geschwindigkeit zu erwarten sind. Dies kann der interessierte Leser auch selbst mit dem Modul "Benchmark" ausprobieren. Die Änderungsfrequenz an CGI-Programmen ist oft sehr hoch, aus diesem Grund verbleibt selten ein CGI-Programm in seiner Ursprungsform, denn Wartungsmassnahmen und Programmerweiterungen sind oft nötig und werden zudem nicht immer von derselben Person durchgeführt. Zusammenfassend kann man den Taint-Modus als Vorfeld-Sicherheitscheck bezeichnen, den es bei Perl als besonderen Service gibt. Grundprinzipien des Taint-Modus Die erste Quelle für den nach Sicherheit strebenden Perl-Programmierer sollte immer das Perlsec-Manual sein. Dort wird in angenehmer Tiefe auf den Taint-Modus eingegangen, der Perl-Programme automatisch Sicherheits-Checks unterzieht. Dieser Laufzeit-Modus wird durch das Flag -T aktiviert, und auch immer dann wenn sich die ID der realen und der effektiven Gruppe oder des Users unterscheidet. Für serverseitige Programme (z.B. CGI-Scripts) sollte man den Taint-Modus als Pflicht ansehen. Es wird sichergestellt, dass die Pfad-Verzeichnisse nicht von anderen beschrieben werden dürfen. Und es werden Variablen daraufhin gecheckt, ob sie von außerhalb gefüllt werden, und somit den Programmablauf (unsinngemäß) beeinflussen können. So ist der Fall denkbar in dem über eine Kommandozeilenoption oder einen `echo $ENV{īVARī} eine Variable gefüllt wird, deren Inhalt in einem system-Aufruf weiterverwendet wird. Würde es jetzt einem Angreifer gelingen, diese Variable zu beeinflussen und dort ein "| rm -r *" hineinzuschreiben, so würde dieser Befehl ausgeführt werden. Eine blitzblank leere Festplatte wäre bei entsprechend gesetzten Rechten das Ergebnis eines solchen Angriffs (manche Leute lassen ihren Webserver ja immer noch als Root laufen). Externe Daten die auf diese Art in ein CGI-Programm gelangen, werden als kontaminiert (engl. Taint = Schmutz) bezeichnet. Sie dürfen im Taint-Modus nicht direkt oder indirekt an Subshells übergeben oder in Befehlen verwendet werden, die auf Dateien und Prozesse zugreifen. Aufgabe des aufmerksamen CGI-Programmierers ist es, diese Daten zu reinigen. Dies kann durch die Entnahme von "gutartigen" Daten aus den Taint-Daten geschehen. Man benutzt zu diesem Zweck die Textfilter-Mechanismen von Perl, mit denen man Teilzeichenketten aus Strings gewinnen kann. Werden aus Taint-Daten die bekannten Substrings $1, $2 usw. gewonnen, so werden diese als "gereinigt" angesehen. Der Perl-Compiler vertraut an dieser Stelle der Wirksamkeit des vom Programmierer eingesetzten Filter. Geht dieser verantwortungsvoll vor, wird er z.B. alle Pipe-Symbole entfernen, um den Aufruf von ungewünschten Dritt-Programmen zu vermeiden. Er kann sich aber auch schnell seiner Aufgabe entledigen und mit $taint_data =~ (.*) Daten die Daten aus der unsauberen Variable schnell eins zu eins in die von Perl als sauber angesehene Variable kopieren. Der Sinn des Taint-Modus wäre an dieser Stelle ad absurdum geführt worden. Zu beachten ist außerdem, dass die Weitergabe von Werten die in Listen stehen nicht auf Taint-Effekte überprüft wird. Beispiel:
Die Befehle Open, Glob und der Aufruf von Programmen mittels Backticks führt ebenfalls zu Sub-Shell-Aufrufen (zur Auflösung der Wildcards ?, * und ~ ). Oft kann der Befehl Open durch Sysopen() ersetzt werden, der einen viel höheren Sicherheitslevel ermöglicht. Probleme mit dem Taint-Modus Wenn man sich zum ersten Mal mit dem Taint-Modus beschäftigt, kann das schon etwas frustrierend sein. Perl beschwert sich anscheinend über jedes kleine Detail. Wenn man ein wenig Erfahrung gewonnen hat, achtet man aber schon von Anfang auf diese Details und schreibt fast automatisch sicheren Code ohne sich erst im Nachhinein große Gedanken darüber zu machen. Anbei einige Tips, die bei der Lösung der häufigsten Probleme bei der Anwendung des Taint-Modus auftreten, erleichtern:
Kontaminierte Variablen Der Taint-Modus betrachtet folgende Variablenkonstellation als kontaminiert:
Dekontaminierung
Die mit Klammern erfaßten Teile eines regulären Ausdrucks werden als frei von Kontaminierung betrachtet -- auch dann wenn die Zeichenkette, die dem regulären Ausdruck zugeführt wurde, kontaminiert ist. Damit ist es möglich, Zeichenketten nach einer Überprüfung gegen einen regulären Ausdruck normal zu verwenden. Natürlich muß darauf geachtet werden, dass diese Überprüfung gewissenhaft geschieht. Wenn ein regulärer Ausdruck nicht der Sicherheitsüberprüfung dient und erkannte Teile davon verwendet werden, sollten sie ggf. mit dem Taint-Befehl als kontaminiert gekennzeichnet werden:
Do's and Don'ts Folgende Operationen sind aus Sicherheitsgründen zu vermeiden und deshalb im Taint-Modus unzulässig , wenn sie von einer kontaminierten Variable abhängen:
Sehr restriktiv ist Perl bei der Ausführung von externen Kommandos und Skripten-- das ist praktisch unmöglich, solange die Umgebungsvariable $ENV{'PATH'} nicht auf einen nicht-kontaminierten Wert gesetzt worden ist. Zusammenfassend läßt sich feststellen, dass viele Techniken, die der Fehlerreduzierung dienen, sich auch auf die Sicherheitsproblematik übertragen lassen. Literatur
|