Alexander (HH): Frage zu Prepared Statement

Beitrag lesen

Moin Moin!

Perls Taint-Mode ist in Sachen Eingabevalidierung extrem hilfreich,

Perl kann ich nicht verwenden, also ich, mein Server schon, wäre mir aber auch zu kompliziert, jetzt noch Perl mit ins Spiel zu bringen.

Wer sagt denn "auch"? "Nur"! ;-)

Perl markiert im Taint-Mode nahezu alles, wass von "außen" kommt (Programmname, Environment, Kommandozeilenparameter, STDIN, gelesene Dateiinhalte, Ergebnisse von vielen Syscalls, als "tainted" ("verschmutzt", "verseucht" trifft es aber besser). Jede Operation mit "tainted" Werten liefert als Ergebnis wieder "tainted" Werte -- oder bricht das Programm mit einer Exeption ("die") ab. Letzteres passiert typischerweise bei exec, system und, wenn man will, bei Zugriffen auf Datenbanken via DBI.

substr($0,0,0) liefert die ersten null Zeichen des Programmnamens - einen Leerstring. Weil $0 aber "tainted" ist, ist das Ergebnis von substr ebenfalls "tainted" -- auch wenn es ein Leerstring ist.

exec() stirbt sofort und gnadenlos, selbst wenn alle Parameter "sauber" sind, aber das Environment noch nicht aufgeräumt wurde. Das wird schließlich auch mit übergeben, wenn auch nicht explizit.

Der einzige Weg, Werte vom tainted-Flag zu befreien, ist, sie mit einer Regular Expression zu testen und den validierten Wert dort herausfischen zu lassen. Das taint-Flag hängt am Wert, nicht an der Variablen. Eine Variable mit "tainted" Wert kann mit einem nicht "tainted" Wert überschrieben werden und ist dann nicht mehr "tainted".

Soll heißen:

  
#!/usr/bin/perl -T -w  
use strict;  
use CGI qw(param);  
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # "böse" Environment-Variablen, alle tainted, bis sie beseitigt wurden  
$ENV{'PATH'}='/bin:/usr/bin'; # $ENV{'PATH'} ist normalerweise tainted, jetzt nicht mehr. Konstanten im Script sind nicht tainted.  
my $app=param('app');  
# $app ist tainted, da aus $ENV oder STDIN abgeleitet  
$app=~m|^(/usr/safe-for-web/bin/[a-z]{3,8})$| or die "Hack mich nicht!";  
$app=$1; # $1 ist der Match innerhalb der Klammern, und per Definition untainted. Ohne diese Zeile bleibt $app tainted und exec stirbt.  
exec $app; # stirbt nicht, da Environment und alle Parameter untainted sind  
# Dafür kann das Script nur Programme in /usr/safe-for-web/bin ausführen, deren Name aus drei bis acht Kleinbuchstaben besteht.  

OK, blödes Beispiel, aber mehr fällt mir gerade nicht ein.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".