include() böse[tm] u.a.?
Gunnar Bittersmann
- php
Hi,
Ich habe eine Datei $HOME/www/Includes/fuss.shtml, die ihrerseits noch Code (SSI und PHP) enthält, der auf dem Server ausgeführt werden muss. In statische Seiten binde ich sie mit SSI ein:
<!--#include virtual="/Includes/fuss" -->
In eine dynamische Seite $HOME/www/foo/bar.php kann ich sie einbinden mit
<?php include('../Includes/fuss.shtml'); ?>
Erste Frage: Wie kann ich den Pfad absolut angeben?
Zweite Frage: Warum kann ich die Endung ".shtml" nicht weglassen?
Dritte Frage: Ist include() böse[tm]? Immer? Warum? Wann nicht? Ist es hier böse? Ich kann sie ja nicht mit
<?php readfile('../Includes/fuss.shtml'); ?>
einbinden, da dann weder der SSI- noch der PHP-Code in dieser Datei ausgeführt werden.
Dazu die vierte Frage (oder ist es schon die achte?): Wird der PHP-Code ausgeführt, kommt beim Client noch der SSI-Code an:
<!--#baz -->
Sollte nicht weiter stören, ist ja ein Kommentar. Wird der SSI-Code ausgeführt, kommt beim Client noch der PHP-Code an:
<?php quz ?>
Stört das im Quelltext? Der Validator sagt, es wäre immer noch valides XHTML 1.0.
Live long and prosper,
Gunnar
Hallo Freunde des gehobenen Forumsgenusses,
Erste Frage: Wie kann ich den Pfad absolut angeben?
Keine Ahnung. Hast du schonmal ausprobiert, einen absoluten Pfad anzugeben?
Zweite Frage: Warum kann ich die Endung ".shtml" nicht weglassen?
Weil du die Datei 'fuss.shtml' und nicht 'fuss' genannt hast.
Wie sollte das System auch zwischen 'fuss.php' 'fuss.txt' 'fuss.shtml' etc...
unterscheiden, die ja alle im selben Verzeichnis liegen können?
Dritte Frage: Ist include() böse[tm]?
Nein.
Immer?
Manchmal.
Warum?
Wenn jemand include($_GET['foo']);
schreibt, dann schon.
Wenn jemand dagegen
$files = array('1' => 'seite1.php', '2' => 'seite2.php', '3' => 'seite3.php');
include(isset($files[$_GET['foo']]) ? $files[$_GET['foo']] : 'index.php');
schreibt, ist das vollkommen in Ordnung.
Leider gibt es Leute, die die erste Variante verwenden.
Wann nicht?
Warum sollte es?
Es ist ein Hilfsmittel, um die Übersicht zu bewahren
(auch wenn Editoren[tm] code-folding können).
Ist es hier böse?
M.E. nicht.
Gruß
Alexander Brock
Hello,
Hallo Freunde des gehobenen Forumsgenusses,
Erste Frage: Wie kann ich den Pfad absolut angeben?
Keine Ahnung. Hast du schonmal ausprobiert, einen absoluten Pfad anzugeben?
Hier hast Du wahrscheinlich die Frage zu wörtlich genommen oder den vergessenen Teil Kontext nicht selbsttätig ergänzt? Es ist tatsächlich ein Problem.
Ich habe einige Kollegen, die mir immer auf ihren lokalen PCs die bunten Seiten fertig machen, die ich dann mit PHP im Hintergrund zusammenbauen muss und "dynamisieren" muss. Ich bekomme also hübsche bunte Frames... Und nun soll das Konstrukt auf dem Server laufen, aber möglichst ohne relative Pfadangaben, da die entstehenden Module auch mal verschoben werden könnten...
Harzliche Grüße vom Berg
esst mehr http://www.harte-harzer.de
Tom
Heißa, Gunnar,
Ich spreche jetzt nicht aus Erfahrung – ich habe noch nie mit SSI gearbeitet – aber vielleicht hilft dir ja das, was ich mal irgendwo gelesen habe.
Erste Frage: Wie kann ich den Pfad absolut angeben?
Vielleicht hilft es, ein $_SERVER['DOCUMENT_ROOT'] davorzusetzen? Du könntest natürlich auch in deiner PHP-Konfiguration den Document-Root in den include_path aufnehmen – dann könntest du den Pfad relativ zum Document-Root und nicht unbedingt zum aktuellen Verzeichnis angeben. Falls du das nicht schon gemacht hast.
Dazu die vierte Frage (oder ist es schon die achte?): Wird der PHP-Code ausgeführt, kommt beim Client noch der SSI-Code an:
<!--#baz -->
Ja, afaik wird in PHP-Dateien SSI-Code nicht ausgeführt. Warum auch immer. Du müsstest also, zumindest nach dem was ich gelesen habe, entweder PHP oder SSI benutzen.
Gautera!
Grüße aus Biberach Riss,
Candid Dauth
Hello,
Vielleicht hilft es, ein $_SERVER['DOCUMENT_ROOT'] davorzusetzen? Du könntest natürlich auch in deiner PHP-Konfiguration den Document-Root in den include_path aufnehmen – dann könntest du den Pfad relativ zum Document-Root und nicht unbedingt zum aktuellen Verzeichnis angeben. Falls du das nicht schon gemacht hast.
Das ist nicht ganz unkritisch.
Der DOCUMENT_ROOT Path wird bei PHP nur aus der Serverkonfiguration ausgelesen und kann (was eigentlich ein Fehler ist, aber trotzdem funktioniert) sowohl mit / am Ende als auch ohne angegeben sein. Wenn man nun einfach den / anhängt zur Sicherheit, dann kann es aber passieren dass man da
/var/www/domain//pfad/script.php
stehen hat. Das funktioniert im ersten Moment zwar auch, kann aber unter gesissen Umständen auch zu Problemen führen. Man wird also nicht drum herum kommen, diesen Root-Path erstmal um Doc zu schicken, bevor man ihn verwendet. Das wiederum erfordert aber bei (faulen) gewissenhaften Programmierern eine Funktion, die am besten gleich in das main.inc.php eingebunden wird, und die eine Konstante DOCROOT erzeugt (oder ähnlich), die dann vollkommen richtig dargestellt ist.
Nun muss man aber auch wieder diese main.inc.php aus jeder Ebene einbinden können, und schon ist man wieder bei meinem Vorschlag von vorhin: setze den include_path entsprechend praktisch und halte Dich strikt an Namenskonventionen, sodass es keine Doubletten zu main.inc.php[1] im lokalen Verzeichnis geben wird!
[1] Name nur symbolisch!
Harzliche Grüße vom Berg
esst mehr http://www.harte-harzer.de
Tom
Vielleicht hilft es, ein $_SERVER['DOCUMENT_ROOT'] davorzusetzen?
Yep, include($_SERVER['DOCUMENT_ROOT'].'/Includes/fuss.shtml');
tut’s. Danke.
Du müsstest also, zumindest nach dem was ich gelesen habe, entweder PHP oder SSI benutzen.
Genau das will ich ja: https://forum.selfhtml.org/?t=113331&m=719313
long and prosper,
Gunnar
Hello,
In eine dynamische Seite $HOME/www/foo/bar.php kann ich sie einbinden mit
<?php include('../Includes/fuss.shtml'); ?>Erste Frage: Wie kann ich den Pfad absolut angeben?
Eigentlich gar nicht.
Du könntest aber einen include_Path bei PHP einstellen, der dann automatisch gewählt wird, wenn die Datei im aktuellen Verzeichnis nicht zu finden ist.
Es gibt noch mehr Krückenlösungen...
Zweite Frage: Warum kann ich die Endung ".shtml" nicht weglassen?
Da solltest Du besser nachfragen, wieso Du sie bei SSI nicht angeben musst.
Das ist recht ungewöhnlich.
Das Include bei PHP findet auf der Dateiebene außerhalb des Bereiches von Apache statt. Da gibt es also auch keine indexes.
Dritte Frage: Ist include() böse[tm]? Immer? Warum? Wann nicht? Ist es hier böse?
Jein. Kommt doch ganz auf Dich an. Es genauso gut oder böse wie alle anderen Executer auch:
Alle Befehle, die die Kontrolle (übergangsweise) an den eingebundenen Befehlsstrom abgeben, sind Sicherheitslücken.
Ich kann sie ja nicht mit
<?php readfile('../Includes/fuss.shtml'); ?>
einbinden, da dann weder der SSI- noch der PHP-Code in dieser Datei ausgeführt werden.
Das kommt auf Dein Konzept an.
Ich hoffe, dass Du hier nicht in zwei Sätzen eine Gesamtabhandlung über CM und die möglichen Methoden erwartest. Das beste wird immer sein, mit der strikten Trennung von Datenmanipulation und Ausgabe zu beginnen. dann kommt man irgendwann ganz automatisch zu einer (relativ sicheren) Template-Engine ohne Lücken.
Dazu die vierte Frage (oder ist es schon die achte?): Wird der PHP-Code ausgeführt, kommt beim Client noch der SSI-Code an:
<!--#baz -->
Sollte nicht weiter stören, ist ja ein Kommentar. Wird der SSI-Code ausgeführt, kommt beim Client noch der PHP-Code an:
<?php quz ?>
Stört das im Quelltext? Der Validator sagt, es wäre immer noch valides XHTML 1.0.
Das würde mich als Programmierer mehr stören, als es den Browser stört. Warum auf die Finger gucken lassen, wie die Seiten im Hintergrund zusammengesetzt werden?
BTW: könntet Ihr alle es bitte unterlassen, diese Code-Kacke einzubauen, und dann die Syntax nicht richtig zu verwenden?
Harzliche Grüße vom Berg
esst mehr http://www.harte-harzer.de
Tom
Da solltest Du besser nachfragen, wieso Du sie [die Endung ".shtml"] bei SSI nicht angeben musst.
Das ist recht ungewöhnlich.
Nö, Tom, der Server sucht sich schon das Passende. Ich mache Referenzen soweit es geht ohne Dateiendungen. Habe ich bspw. foo.shtml und irgendwann muss mehr serverseitige Logik rein als SSI bietet, dann wird daraus eben foo.php. Aber ich muss keinen einzigen Link ändern, wenn ich immer schon auf http://example.net/foo referenziert habe.
Das Include bei PHP findet auf der Dateiebene außerhalb des Bereiches von Apache statt. Da gibt es also auch keine indexes.
Das erklärt, warum die Dateiendung bei PHP ranmuss.
BTW: könntet Ihr alle es bitte unterlassen, diese Code-Kacke einzubauen, und dann die Syntax nicht richtig zu verwenden?
Also nicht
[сode lang=php]<?php foo ?>[/сode]
sondern
[сode lang=xml]<?php [сode lang=php]foo[/сode] ?>[/сode]
Meinst du das?
Live long and prosper,
Gunnar
Hello,
Da solltest Du besser nachfragen, wieso Du sie [die Endung ".shtml"] bei SSI nicht angeben musst.
Das ist recht ungewöhnlich.Nö, Tom, der Server sucht sich schon das Passende. Ich mache Referenzen soweit es geht ohne Dateiendungen. Habe ich bspw. foo.shtml und irgendwann muss mehr serverseitige Logik rein als SSI bietet, dann wird daraus eben foo.php. Aber ich muss keinen einzigen Link ändern, wenn ich immer schon auf http://example.net/foo referenziert habe.
ungewöhnlich ist aber, dass der Server sich nicht nur die Initial-Ressource selber suchen darf, sondern auch noch ihren Applikationstyp. Das ist eine Art von "Automatik", die ich dem Apachen niemals erlauben würde.
Wenn er nach einer index.* suchen darf und das * dabei durch html, shtml, php, phtml ersetzen darf, dann ist das noch überschaubar. Wenn er aber aus ./ sich irgendwas raussuchen darf, dann halte ich das schon für äußerst bedenklich.
Harzliche Grüße vom Berg
esst mehr http://www.harte-harzer.de
Tom
Wenn er nach einer index.* suchen darf und das * dabei durch html, shtml, php, phtml ersetzen darf, dann ist das noch überschaubar. Wenn er aber aus ./ sich irgendwas raussuchen darf, dann halte ich das schon für äußerst bedenklich.
Nein, nicht irgendwas, sondern eins aus foo.html, foo.shtml, foo.php, …
Warum sollte der Apache bei foo nicht das tun dürfen, was er bei index auch darf?
Live long and prosper,
Gunnar
PS. War die Verschachtelung mit [сode] so korrekt? https://forum.selfhtml.org/?t=113331&m=719313
Moin!
Ich habe eine Datei $HOME/www/Includes/fuss.shtml, die ihrerseits noch Code (SSI und PHP) enthält, der auf dem Server ausgeführt werden muss.
Regel Nummer 1: Man kann SSI und PHP nicht mischen in einer Datei und erwarten, dass beide Codes wirken. Sowas geht mit Apache 1.3 schon mal generell gar nicht, und der Apache 2 müßte für sowas extra konfiguriert werden - womit ich mich noch nicht näher beschäftigt habe, also auch nicht sagen kann, ob und wie es geht.
Aber es ist ja kein Problem, das, was SSI tun soll, auch mit PHP zu tun. Man kann also den SSI-Teil dieser fuss.shtml auch komplett in PHP erledigen.
Man kann der Einfachheit halber die .shtml-Datei dann zu einer .php-Datei machen.
Und wenn man die dann mit SSI einbindet, wird - oh wunder - das PHP ausgeführt.
<!--#include virtual="/Includes/fuss.php" -->
Es funktioniert sogar (wenn man das braucht) mit GET-Parametern, die im PHP dann zur Verfügung stehen:
<!--#include virtual="/Includes/fuss.php?wert=angabe" -->
Mit anderen Worten: Es gibt eigentlich keinen Grund, SSI und PHP in einer Datei zu mischen.
Und es gibt auch keinen Grund, ungeparstes SSI oder PHP an den Browser zu schicken. Wobei das beim SSI noch nicht so wahnsinnig grausam ist, aber PHP-Code böte unter Umständen dann doch die Offenbarung von Angriffspunkten - und das sollte man natürlich vermeiden.
- Sven Rautenberg
Regel Nummer 1: Man kann SSI und PHP nicht mischen in einer Datei und erwarten, dass beide Codes wirken.
Hi Sven,
Das ist mir schon klar; ich will auch gar nicht, dass beide Codes wirken. Sie tun ja auch dasselbe, nämlich den Zeitpunkt der letzten Änderung ausgeben …
Aber es ist ja kein Problem, das, was SSI tun soll, auch mit PHP zu tun. Man kann also den SSI-Teil dieser fuss.shtml auch komplett in PHP erledigen.
… und dafür muss man ja nicht immer gleich die PHP-Engine anschmeißen, wenn SSI reicht. Nur, wenn ich auf einer Seite für andere Dinge PHP brauche, kann ich die Datei nicht mit SSI einfügen.
Natürlich könnte ich zwei getrennte Dateien fuss.shtml und fuss.php für exakt denselben Zweck anlegen. Nur unschön, dass dann Änderungen jeweils in beiden Datein gemacht werden müssen.
Oder stückeln in fuss_anfang und fuss_ende, dann mit SSI:
<!--#include virtual="/Includes/fuss_ballen" -->
<!--#config timefmt="%Y-%m-%dT%H:%M%z" --><!--#echo var="LAST_MODIFIED" -->
<!--#include virtual="/Includes/fuss_hacken" -->
und mit PHP:
<?php
[code lang=php] readfile($_SERVER['DOCUMENT_ROOT'].'/Includes/fuss_ballen');
echo date('Y-m-d\TH:iO', getlastmod());
readfile($_SERVER['DOCUMENT_ROOT'].'/Includes/fuss_hacken');
?>[/code]
Auch nicht sonderlich elegant.
Mit anderen Worten: Es gibt eigentlich keinen Grund, SSI und PHP in einer Datei zu mischen.
Die Alternative wären wohl zwei Dateien, so oder so.
Und es gibt auch keinen Grund, ungeparstes SSI oder PHP an den Browser zu schicken.
Das wäre die Folge, wenn ich nur eine Datei haben möchte. Oder geht’s auch mit einer Datei anders?
aber PHP-Code böte unter Umständen dann doch die Offenbarung von Angriffspunkten
Prinzipiell ja, in meinem Fall stehen keine Geheimnisse drin.
Live long and prosper,
Gunnar
Oder geht’s auch mit einer Datei anders?
Hm, ich könnte natürlich in PHP eine Funktion schreiben, die fuss.shtml nicht unverändert ausgibt, sondern einliest, den Anfang ausgibt bis zu der Stelle, wo die SSI-Anweisungen stehen, dann das Datum schreibt und zuletzt den Rest nach den SSI-Anweisungen ausgibt.
Danke, dass ihr mich zum Nachdenken anregt! ;-)
Live long and prosper,
Gunnar
Moin!
Aber es ist ja kein Problem, das, was SSI tun soll, auch mit PHP zu tun. Man kann also den SSI-Teil dieser fuss.shtml auch komplett in PHP erledigen.
… und dafür muss man ja nicht immer gleich die PHP-Engine anschmeißen, wenn SSI reicht. Nur, wenn ich auf einer Seite für andere Dinge PHP brauche, kann ich die Datei nicht mit SSI einfügen.
Du argumentierst mit Performancegründen. Dabei wird dein SSI ohnehin als HTTP-Subrequest behandelt wird, d.h. du beschäftigst allein für das SSI erneut den gesamten Webserver mit dem Subrequest. Und PHP als Modul in den Apachen gebunden sollte sich hinsichtlich der Ausführungszeit auch nicht groß unterscheiden.
Ich behaupte einfach mal: Wenn das Parsen und Einbinden eines PHP-Skriptes, welches den Fuss erstellt, tatsächlich Performanceprobleme mit sich bringt, dann hast du schon wesentlich früher ganz andere Probleme, würde ich meinen.
Natürlich könnte ich zwei getrennte Dateien fuss.shtml und fuss.php für exakt denselben Zweck anlegen. Nur unschön, dass dann Änderungen jeweils in beiden Datein gemacht werden müssen.
Hinsichtlich der hochgeschätzten Performance aber wesentlich ratsamer, denn die nutzlosen SSI-Kommentare müssen ja von der PHP-Engine auch geparst werden, und die nutzlosen PHP-Bereiche von der SSI-Engine. Das ist ebenso unverzichtbar wie das Abschalten der Multiviews und wiedereinführen der Dateiendung bei der SSI-Einbindung, denn das Suchen einer passenden Ressource kostet vollkommen unnötig Zeit.
aber PHP-Code böte unter Umständen dann doch die Offenbarung von Angriffspunkten
Prinzipiell ja, in meinem Fall stehen keine Geheimnisse drin.
In den diversen Inkarnationen des phpBB stehen auch keine Geheimnisse drin - trotzdem finden sich dort immer wieder Sicherheitslücken. Mit anderen Worten: Es geht weniger um das, was man als "Geheimnis" bezeichnen würde, sondern um eventuelle Ansatzpunkte, über deren Nutzbarkeit du ggf. noch gar nicht nachgedacht hast. Gerade bei auch einzeln aufrufbaren PHP-Codefragmenten und u.U. unglücklich gewählter PHP-Konfiguration bieten sich eventuell ungeahnte Angriffsmöglichkeiten.
- Sven Rautenberg
Sven,
Moin!
Aber es ist ja kein Problem, das, was SSI tun soll, auch mit PHP zu tun. Man kann also den SSI-Teil dieser fuss.shtml auch komplett in PHP erledigen.
… und dafür muss man ja nicht immer gleich die PHP-Engine anschmeißen, wenn SSI reicht. Nur, wenn ich auf einer Seite für andere Dinge PHP brauche, kann ich die Datei nicht mit SSI einfügen.
Du argumentierst mit Performancegründen.
Naja, vielleicht schiebe ich die auch vor, weil ich PHP nicht sonderlich mag.
Ich bin mir auch durchaus bewusst, dass ich den eventuellen Performance-Gewinn, den ich mit SSI erziele, durch das Weglassen der Dateiendungen mehr als verspiele.
Da hab ich auch gar nicht die Perfomance im Auge, sondern die bequeme Wartbarkeit der Website; dass bei späteren Veränderungen so wenig wie möglich in so wenig wie möglich schon bestehenden Datein geändert werden muss.
Vielleicht verzichte ich auch wieder auf die Ausgabe des Datums in der Fußzeile oder baue ein JavaScript ein, dass dieses aus der ohnehin vorhandenen Meta-Angabe im head ausliest – der Informationsverlust für User ohne JavaScript dürfte hier noch vertretbar sein. Dann benenne ich einfach die Datei "fuss.shtml" in "fuss" um, der Include muss ja nicht mehr durch die SSI-Engine – fertig. In keinem HTML-Dokument muss ich etwas verändern, weil dort überall ja schon immer auf "fuss" referenziert wurde.
Beim Includen mit PHP scheint mir, dass man – ohne riesigen Aufwand zu betreiben – für ewig an die einmal gewählte Lösung gebunden ist. Hat man einen Schnipsel mit readfile()
eingebunden, kann man in diesen kein PHP einfügen, da man den dann ja mit include()
einfügen müsste und das in allen HTML-Quelltexten ändern müsste. Bliebe, von vornherein include()
zu verwenden – ob das so sinnvoll ist?
Live long and prosper,
Gunnar
Moin!
Du argumentierst mit Performancegründen.
Naja, vielleicht schiebe ich die auch vor, weil ich PHP nicht sonderlich mag.
Aha. ;)
Da hab ich auch gar nicht die Perfomance im Auge, sondern die bequeme Wartbarkeit der Website; dass bei späteren Veränderungen so wenig wie möglich in so wenig wie möglich schon bestehenden Datein geändert werden muss.
Dieses Argument kann ich nur teilweise nachvollziehen.
Gewiß, es ist eine Erleichterung, wenn man beispielsweise seine Grafiken von ehemals GIF jetzt auf das kleinere PNG umstellt und in den einbindenden Seiten nichts umstellen muß.
Andererseits: Wenn du deine Fußzeile einmal gültig eingebunden hast, wäre ja lediglich eine Veränderung am Dateinamen bzw. dessen Endung relevant für eine daraus folgende Änderung in allen einbindenden Dateien - inhaltliche Veränderungen beträfen die Einbindung nicht.
Bei einer Umstellung der Technik z.B. von PHP auf Perl ist es ja aber nicht so, dass die Dateibezeichnung, insbesondere der Dateiname, zwingend geändert werden müßte. Die SSI-Einbindung nutzt den Apache zum Auffinden der korrekten Datei, es wirken also auch Weiterleitungen. Und generell favorisiere ich, sofern in irgendeiner Weise Template-Engines zur Anwendung kommen, sowieso den generellen Einsatz von mod_rewrite für den gesamten URL-Raum, um schon gleich im allerersten Schritt eine Virtualisierung des URL-Raumes zu erreichen, den man dann auf physikalische Dateien abbilden kann, ohne eine zwangsweise 1:1-Verknüpfung zwischen URL und physikalischer Datei benutzen zu müssen.
Den zu errichtenden URL-Raum virtuell zu gestalten stellt nach meiner Meinung jedenfalls einen erheblichen Vorteil für die Programmierung dar, insbesondere beim Einsatz von Template-Engines.
Beim Includen mit PHP scheint mir, dass man – ohne riesigen Aufwand zu betreiben – für ewig an die einmal gewählte Lösung gebunden ist. Hat man einen Schnipsel mit
readfile()
eingebunden, kann man in diesen kein PHP einfügen, da man den dann ja mitinclude()
einfügen müsste und das in allen HTML-Quelltexten ändern müsste. Bliebe, von vornhereininclude()
zu verwenden – ob das so sinnvoll ist?
Mit einer vernünftigen Template-Lösung kämen solche Probleme wohl erst garnicht auf, weil man es grundsätzlich vermeiden könnte, eine Inhaltsdatei mit ergänzender, mitten im Content eingefügter Programmierung zu verunstalten.
- Sven Rautenberg