25.03.2007
PHP: Wo bin ich, wo will ich hin — Pfade Switchen
Häufig gebraucht wird, dass man den aktuellen Pfad herausfindet und von dort innerhalb eines CMS- oder Shopsystem in einen anderen bekannten Ordner wandern muss. Den Ort hole ich mir mit self_php. Mir wurde zwar gesagt, dass $_SERVER['SELF_PHP'] bei manchen Server-Einstellungen in die Hose geht, wenn der Aufruf via include erfolgt, aber soweit ich feststellen konnte, klappt das besser als $_SERVER['PATH_TRANSLATED'] oder getcwd(), ergo verwende ich am liebsten $_SERVER['SELF_PHP']. Danach wird augehend von dem Ort, brav der Weg zu Fuß gegangen:
$actDir = $_SERVER[PHP_SELF];$actDirArr = explode('/',$_SERVER[PHP_SELF]);array_pop($actDirArr);$actDir = array_pop($actDirArr);$actDir = file_exists('root.info')? 'root' : $actDir;switch($actDir){case root:$pathAdmin = "admin/";$pathRoot = "";$pathTemplates = "templates/";break;case admin:$pathAdmin = "";$pathRoot = "../";$pathTemplates = "../templates/";break;}
Die Methode ist simple, übersichtlich und einmal von dem include-Issue, das ich selbst noch nicht beobachtet habe, relativ Narrensicher. Root einer Installation ist nicht immer auch das Rootverzeichnis des Hostingplatzes oder Servers. Ergo lege ich mir eine Datei (root.info), welche leer sein darf, in das Rootverzeichnis, nach der ich fragen kann, oder frage nach einem Ordner, der vom Root aus eineindeutig ist.
Übrigens die Methode den Pfad per array_pop zu ermitteln, habe ich mir von Holger Struck abgeschaut. Wo er ihn her hat weiß ich nicht, aber ich finde es praktisch und schnell und hier auch gleich im doppelten Sinne brauchbar. Denn es kürzt den Array um den letzten Eintrag, der Datei, aus der der Pfad $_SERVER['SELF_PHP'] abgerufen wird und gibt beim zweiten Mal, gleich auch den Namen den aktuellen Ordners Preis. Praktisch wäre es, wenn man nun einem Switch nachträglich einen weiteren Case anhängen könnte. Muss ich mal drüber nachdenken ... Wenn mir oder einem Käpsele in den Kommentaren etwas einfällt, gibt es ein Update.
Apropos: dem Thema ging ich schon einmal auf die Spur und habe mir verzweifelt einen abgekrampft: Kein Schleifchen um die PHP Schleife
Update: Und schon gibt es etwas Neues und lesenswert im Rahmen der Sicherheit von PHP-Applikationen. Mathias Bank macht mich in den Kommentaren auf eine Sicherheitslücke bei $_SERVER[SELF_PHP] aufmerksam.
A predominant PHP developer (whose name I didn't get permission to drop, so I won't, but many of you know who I mean) has been doing a bunch of research related to Cross Site Scripting (XSS), lately. It's really opened opened my eyes to how much I take user input for granted.
Don't get me wrong. I write by the "never trust users" mantra. The issue, in this case, is something abusable that completely slipped under my radar.
[...]
Only a fool would "echo $_GET['param'];" (and we're all foolish sometimes, aren't we?). [...]What I forgot about, as I suspect some of you have, too (or maybe I'm the only loser who didn't think of this (-; ), is that $_SERVER['PHP_SELF'] can be manipulated by the user.
How's that? If I put a script at /simple/test.php, $_SERVER['PHP_SELF'] should always be "/simple/test.php", right?
Wrong, again.
[...]
I hope that the problem is now obvious. Consider:
http://example.com/tests/simple.php/%22%3E%3Cscript%3Ealert('xss')%3C/script%3E%3CfooThe output suddenly becomes very alarming:
<html><body><form action="/tests/simple.php/"><script>alert('xss')</script><foo"><input type="hidden" name="submitted" value="1" /><input type="submit" value="Submit!" /></form></body></html>If you ignore the obviously-incorrect
tag, you'll see what's happening. The would-be attacker has successfully exploited a critical (if you consider XSS critical) flaw in your logic, and, by getting a user to click the link (even through a redirect script), he has executed the Javascript of his choice on your user's client (obviously, this requires the user to have Javascript enabled). My alert() example is non-malicious, but it's trivial to write similarly-invoked Javascript that changes the action of a form, or usurps cookies (and submits them in a hidden iframe, or through an image tag's URL, to a server that records this personal data).
Quelle: blog.phpdoc.info: XSS Woes (Im Google-Cache)
Natürlich habe ich es gleich lokal umgeschrieben und getestet, doch auf meiner Apache-Installation auf einem Windowsrechner, funktioniert __FILE__ nicht, also zurück zu $_SERVER[SELF_PHP]. Ich benötige in diesem Fall keine Parameter, ich kann also alles, was nach dem ersten ".php" kommt, das noch ganz unter meiner Kontrolle, bzw. unter der Kontrolle des Servers auf dem das Skript gehostet ist, in die Tonne geben. Und schon funktioniert es auf beiden Systemen und sicher vor Manipulation. Im Folgenden der Abschnitt, der sich ändert, damit hier nichts passieren kann. Das gesamte Skript gibt es in einer kleinen Minidemo unter http://blog.templaterie.de/minidemo
$getDir = $_SERVER[PHP_SELF];$actDirArr = (explode('.php',$getDir));$actDirArr = explode('/',$actDirArr[0]);$actDir = array_pop($actDirArr);$actDir = array_pop($actDirArr);$actDir = file_exists('root')? 'root' : $actDir;- Siehe PHP-Skripte der Minidemo:pathfinder.phps & index.phps
Und schon wieder ein dickes Danke schön an Mathias für den wichtigen Sicherheits-Tipp.
Filed under: Programmierung
1 Comment
March 25th, 2007 at 08:49
Du musst aber aufpassen und berücksichtigen, dass $_SERVER["PHP_SELF"] vom Benutzer kommt und damit fehlerhafte Informationen haben kann. Es ist den meisten nicht bewusst, dass über $_SERVER["PHP_SELF"] sehr einfache XSS-Hacks möglich sind. Einen guten Artikel hierzu gibt es auf http://blog.phpdoc.info/archives/13-guid.html, derzeit leider nur über Google-Cache erreichbar.
Um den Pfad der aktuellen Datei herauszufinden, verwende ich die PHP-Konstante __FILE__.