Sven Rautenberg: Skript enthält Sicherheitslücke, NICHT VERWENDEN!

Beitrag lesen

Moin!

[x] gefixt. Danke!

„MyShellEscape()” - Autsch.

Doppel-Autsch...

Abgesehen davon, dass deine Escape-Funktion jede Menge an Eventualitäten nicht berücksichtigt (Jonathan sprach das ja bereits an), wofür bringt PHP bitte schön eine Funktion escapeshellarg() mit?

Was mir an dem ganzen Skript absolut nicht gefällt, sind die diversen beiläufigen System-Shell-Aufrufe, die an den verschiedendsten Orten eingestreut werden, ohne sofort ins Auge zu fallen.

Dabei halte ich es insbesondere für problematisch, dass es gar keine Regelmäßigkeit gibt, ob für eine Aktion jetzt nur PHP-Mittel benutzt werden, oder ob ein externes Shell-Kommando zum Einsatz kommt. Mal ist es so, mal ist es anders.

Und wenn dann die Shell bemüht wird, um irgendeine Trivialität zu erledigen, mangelt es notorisch immer wieder am Escaping! Dabei ist es aus meiner Sicht absolut unerheblich, ob die jeweils benutzten Variablen eigentlich statische und vernünftige Werte enthalten - Fakt ist, dass sie dies nicht zwingend in jeder Situation tun müssen, und dass es vom Sicherheitsapekt her eine extrem schlechte Idee ist, in einer konkreten Programmzeile eine potentielle Sicherheitslücke offen zu lassen mit dem Argument, dass man eben anderswo, wo der Aufruf dieser Sicherheitslücke gestartet wird, ganz besonders aufpasst, dass auch nichts passiert.

Resultat: Anstatt an genau einer Stelle aufzupassen und Gegenmaßnahmen zu ergreifen, vervielfältigt man das Problem, indem man jetzt an jeder Stelle, die die Funktion aufruft, aufpassen und Gegenmaßnahmen ergreifen muss. Das ist allein schon vom Effektivitätsgedanken her Unsinn, kein Programmierer schreibt Code zweimal, wenn er ihn nur einmal schreiben muss. Von der unweigerlichen Gefahr, das Aufpassen an einer entscheidenden Stelle doch einmal vergessen zu können, ganz abgesehen.

Im Einzelnen:

if (! file_exists($config['userfile'])) {  
 system("touch ".$config['userfile']);  
}  
  
if (! file_exists($config['htaccessfile'])) {  
 system("touch ".$config['htaccessfile']);  
}

http://de.php.net/touch

$users=trim(cut -d: -f1 $userfile);
http://de.php.net/file_get_contents + explode + explode + Arraybearbeitung

Weiteres Problem: Unter SuSE hast du Glück, htpasswd2 existiert, liegt in /usr/bin und somit im Bereich von $PATH.
Unter Debian und Unbuntu sieht das anders aus, dort heißt das Tool (ja, auch bei Apache 2) htpasswd und wird somit von deinem Programm nicht gefunden.
Ich meine mich zu entsinnen, dass wenn man Apache selbst kompiliert zudem htpasswd standardmäßig in /usr/sbin landet und somit für einen normalen User nicht im Bereich von $PATH enthalten ist.

Auf meinem Gentoo-System existiert nur /usr/sbin/htpasswd, und ein Link /usr/sbin/htpasswd2 auf dieses Programm.

Warum willst du überhaupt htpasswd verwenden? Wie Sven bereits sagte, solltest du die Passwörter grundsätzlich erst mal auf MD5-Basis haschen, da diese Hashs sowohl unter Windows, wie auch unter Unix funktionieren (htpasswd -m ist dein Freund).

Ich habe keine grundsätzlichen Einwände, zur Erreichung rascher Ergebnisse genau die Tools einzusetzen, die dafür geschaffen wurden, rasche Ergebnisse zu erzielen.

Das Problem ist nur, dass es sachgemäß passieren muss. Kommandozeilentools in der Hand eines fähigen Admins sind eine gute Sache. Integriert in ein Webskript aber erhalten sie potentiellen Kontakt zu einer großen Welt des Bösen - also muss man hier extreme Vorsicht walten lassen.

htpasswd ist halt das ideale Tool, um schnell und ohne Umwege Useraccounts in einer .htpasswd-Datei zu managen. Nur: Wenn ich dieses Tool nutze, dann auch zu 100% für alle Funktionen, und natürlich entsprechend abgesichert.

Da du die Benutzer ja sowieso manuell, also mit Lese- und Schreibbefehlen von PHP löschst, anstatt mit htpasswd, würde ich in diesem Fall dazu tendieren, die Benutzer auch mit reinem PHP anzulegen, wodurch du nicht vom von der Verfügbarkeit von htpasswd abhängig bist.

Das ist sicherlich eine sehr gute Idee. Viele Shared-Hosting-Accounts verbieten den Zugriff auf Funktionen wie system(), um genau solche Probleme mit Skripten zu verhindern, wie hier in der ersten Version zu sehen war.

Eine entsprechende Funktion zum MD5-Hash für den Apache findest du hier.

Das Problem ist halt: Solch eine Funktion muss man entweder aufwendig selbst schreiben, oder in den Weiten des Webs ausfindig machen.

Auf der anderen Seite: Solch eine Aufgabe ist schon so uralt und hat schon so viele Admins geärgert, dass es extrem unwahrscheinlich ist, dass da noch niemand was erstellt hat. Und tatsächlich: Da gibts auch was von PEARiopharm! - dummerweise nur zum Handling des .htaccess-Files, nicht für .htpasswd. Was mich zu dem Schluss kommen läßt, dass entweder der Bedarf doch nicht so riesig ist, weil für größeren Bedarf kein .htpasswd eingesetzt wird, sondern z.B. mod_access_mysql mit Datenbankanbindung (und wie man die DB mit PHP nutzt, ist bekannt), und für den kleinen Bedarf anscheinend der Shell-Aufruf von htpasswd ausreicht.

- Sven Rautenberg

--
"Love your nation - respect the others."