Tutorial : Sichere CGIs auf der Homepage
      
Shopsoftware Shopsystem
  Home     Download     News     Kontakt     Impressum     Sitemap  

Demo-Version   
Häufige Fragen   
Module und Preise   
Wie bestellen   
Support   
AnfrageAnfrage   
TutorialsTutorials
Partnerprogramm   
Über interaktiv.net   
Leistungen   
Referenzen   
Sie sind hier  :  Startseite Support Tutorials
Sichere CGIs auf der Homepage


Was ist ein sicheres CGI
Welche Rechte hat ein CGI Prozess
Systembefehle über CGIs ausführen
Wie verhindere ich den Missbrauch von Pipes
Sendmail - Ein mögliches Risiko
Weiterführendes



Was ist ein sicheres CGI

In diesem Artikel soll nicht von einem sicheren CGI im Sinne von Absturzsicherheit die Rede sein. Vielmehr geht es hier darum wie ein Eindringen von böswilligen Hackern in das System über etwaige Sicherheitslücken in einem fehlerhaften CGI verhindert wird.

Sicherheitslöcher in eigenen verwendeten CGIs verhindern, erkennen und ggf. beseitigen, dafür trägt in erster Linie der Webmaster selbst die Verantwortung. Diese Verantwortung erstreckt sich nicht nur auf das eigene Web sondern auf den gesamten Server - darüber sollte sich jeder Webmaster im Klaren sein! Denn auf einem Server ist ja nicht nur das eigene Web gehostet sondern Einige bis Viele... Mit einem sicheren CGI im Sinne dieses Artikels hat ein böswilliger Cracker keine Chance in das System einzudringen, Daten zu klauen oder anderweitigen Schaden zu verursachen.


Welche Rechte hat ein CGI Prozess

Das hängt von der Konfiguration des Webservers ab! Von einigen Providern weiß ich dass sie den Apache als Root (Root ist der Superuser unter LINUX - der darf Alles) laufen lassen, das bringt gewisse Vorteile in der Administration, mit Rootrechten darf der Apache beispielsweise in einem jeden Homepageverzeichnis die Logfiles schreiben was andererseits einen erhöhten Verwaltungsaufwand erfordern würde, wenn das nicht so wäre. Dagegen ist ja auch nichts einzuwenden... aber: Jeder CGI - Prozess welcher als Kindprozess des HTTP - Daemons Apache gestartet wird sollte nicht als Root laufen und genau das liegt in den Händen des Providers! Lassen wir also ein CGI unter group (das ist die Regel) oder other laufen, aus diesem Grunde sollten auch die Ausführungsrechte eines CGIs auf owner/group/other: ausführen gesetzt werden.


Systembefehle über CGIs ausführen

Mit dem vorangegangenen Abschnitt wurde deutlich gemacht, dass ein CGI unter der Benutzergruppe group/other üblicherweise auf dem Server läuft und damit auch die Berechtigungen besitzt welche diese administrativen Benutzergruppen haben.

Nehmen wir einmal an, Sie haben ein CGI geschrieben welches einen <input name=string> ganz einfach an das System übergibt mit $ergebnis = qx|string| und Sie geben $ergebnis im Browser aus... das funktioniert doch toll, nicht wahr? Indes: Es ist nicht das was Sie haben wollen denn jeder könnte hier ja eingeben rm * und alle Scripte sind weg. Deswegen wird wohl niemand erlauben Systembefehle welche ein Jeder im Browser eingeben kann per CGI ausführen zu dürfen...

Und nun haben Sie sich ein CGI downgeloadet womit über den Browser ein ping Kommando abgesetzt werden kann, coole Sache! Aber versäumen Sie bitte nicht, das Script mal etwas näher in Augenschein zu nehmen! Schauen Sie in die Unterfunktionen nach Konstrukten wie $v = `kommando` oder system(kommando) oder qx/kommando/ oder open PIPE, "| kommando" ... ! Ups, das sind da Systembefehle!

Ja was könnte denn passieren? Nun, über ein Pipe kann jeder ein weiteres Kommando an den Eingabestring dranhängen, wobei es völlig uninteressant ist ob der Parameter zum Ersteren Kommando einen Sinn macht!

Zum Verständnis: Geben Sie mal auf der Kommandozeile ein

dir interaktiv:

Sie erhalten Datenträger nicht gefunden oder so. Logisch, denn Laufwerke haben nur einen einzigen Buchstaben. Aber nun geben Sie mal ein:

dir interaktiv: | dir c:

... Jupp! Sie sehen das Ergebnis von dir c:! Und nun erinnern Sie sich wieder an das ping Script, da steht

$pingergebnis = qx(ping -c 5 $eingabestring);

Wobei das $pingergebnis später im Browser angezeigt werden soll. Ein frecher Hacker denkt jedoch nicht im entferntesten daran irgendeine IP in seinen Browser einzugeben, er gibt ein:

denkste | ls -la

... und sieht das komplette Directory Listing des Verzeichnisses /cgi-bin/! Natürlich könnte er auch noch andere Kommandos absetzen. Aber schauen wir was da wirklich abläuft, beim PERL Interpreter kommt nämlich das hier an:

$pingergebnis = qx(ping -c 5 denkste | ls -la);

Somit steht in $pingergebnis die Ausgabe von ls -la (List Dir Longformat versteckte Dateien). Genau das hätten Sie vermeiden können, wenn Sie den Eingabestring geprüft hätten ob da wirklich nur eine IP eingegeben wurde und weiter nichts.


Wie verhindere ich den Missbrauch von Pipes

Wenn sich Systembefehle in einem CGI nicht vermeiden lassen checken Sie den Inputstring welcher als Parameter an den Systembefehl übergeben wird sorgsam ab! Dabei ist es manchmal einfacher einen String auf erlaubte Zeichen zu prüfen als auf das Vorhandensein von unerlaubten Zeichen. Um im o.g. Beispiel zu bleiben sollte eine IP an das ping Kommando übergeben werden und weiter nichts. Prüfen Sie in diesem Falle einfach ob eine IP - Addresse eingegeben wurde:

# Eine IP auf Syntax prüfen like 127.0.0.1
sub isip{
   my $ip = $_[0];

   # ersteinmal prüfen, ob Punkte im String enthalten sind
   if (not ($ip =~ /\./)) { return 0;}

   # prüfen ob keine anderen Zeichen als Digits oder Punkt
   if ( $ip =~ /[^0-9\.]/ ){ return 0;}

   # Das Splitting muss genau 4 Teile ergeben
   my $val = my($a, $b, $c, $d) = split(/\./, $ip);
   if( $val != 4 ){ return 0;}

   # Range prüfen
   if ( ($a <0 || $a >255) || ($b <0 || $b >255) || ($c <0 || $c >255) || ($d <0 || $d >255) ){
    return 0;
   }

   # Alles 0 darf nicht sein
   if ( ($a == 0) && ($b == 0) && ($c == 0) && ($d == 0) ){
    return 0;
   }

   # Alles 255 darf auch nicht sein
   if ( ($a == 255) && ($b == 255) && ($c == 255) && ($d == 255) ){
    return 0;
   }

   # Alles OK
   return 1;
}


Ein Modul was Ihnen genau diese Arbeit abnehmen kann ist das web.pm welches neben vielen anderen interessanten Funktionen die Methode isIP("ipstring") zur Verfügung stellt. Und hier noch ein Beispiel zu einer Funktion welche prüft ob es sich beim eingegebenen String um einen Domänen-Namen handelt:

sub chkstr{
 my $s = shift;
 if( $s =~ /[^a-z0-9\.-]/i ){ return 0 }
 else { return 1 }
}

Diese Funktion gibt den Wert 1 zrück wenn das Argument ein syntaktisch gültiger Domänen-Name ist, wenn nicht ist der Rückgabewert 0.


Sendmail - Ein mögliches Risiko

Weithin bekannt und gern genutzt ist der Mail Transfer Agent sendmail welcher i.d.R. unter /usr/sbin/sendmail vom Provider zur Verfügung gestellt wird. Mit sendmail können Mails recht einfach an beliebige eMail-Adressen geschickt werden ohne dass sich der Absender um die Zustellung kümmern muss. Aber Vorsicht, denn üblicherweise wird für die Verwendung von sendmail ein Handler auf ein Pipe geöffnet und der Handler beschrieben. Sie sollten in jedem Falle auch hier alle Eingaben des Benutzers in den Browser auf unerlaubte Zeichen prüfen.

Interessante Möglichkeiten bietet das Modul Net::SMTP womit sich ein Systemcall von sendmail erübrigt. Mit diesem Modul wird eine Mail nicht an einen Handler bzw. über ein Pipe an sendmail übergeben sondern über den TCP Stack und Port 25 (SMTP Protokoll).

Wenn der SMTP Hostname bekannt ist wo sich der eMail Account des Empfängers befindet, können Sie Mails mit Net::SMTP auch direkt dorthin schicken. Diese Art der Mailzustellung bietet sich beispielsweise für Feedback Formulare an, nämlich da wo der Empänger der Mail fest eingebaut ist.


Weiterführendes

Es liegt auf der Hand dass ein derartig umfangreiches Themengebiet nicht in einem kleinen Artikel abgehandelt werden kann. Neben der Möglichkeit von Sicherheitslücken in CGIs aufgrund ungefilterter Eingaben und deren Übergabe an Systembefehle gibt es auch noch andere Punkte welche in dieser Hinsicht beachtenswert sind (zum Beispiel das Erlauben von File Uploads). Auf den Seiten von Wolfgang Wiese finden Sie eine größere Abhandlung der gesamten Problematik CGI Sicherheit. Und sollten Sie einen Verdacht haben, dass auf Ihrem Server irgendwas nicht stimmt in Fragen Sicherheit, so wenden Sie sich vertrauensvoll an Ihren Internet Service Provider.
interAKTIVnet GmbH
Otto-Lilienthal-Str. 36
71034 Böblingen
Tel. 07031-714740
Fax 07031-714744
info@interaktiv.net