TS: PHP include-Path und open_basedir

Hallo und sonnigen Nachmittag, wo auch immer auf dieser Welt,

ich bitte um eure fachkundige Meinung:

  1. PHP sucht Includes in eigens dafür festzulegenden Include-Pathes. Dabei werden die Pfade in der angegebenen Reihenfolge durchsucht und die Suche bei Erfolg abgebrochen. Bei Misserfolg wird eine Fehlermeldung generiert.

Soweit ist alles super. Hat schon das gute alte DOS so gemacht bei der Suche nach Programmen oder Dateien, un das hat sich bewährt.

  1. Ich gehe davon aus, dass man den Quellcode von Dateien, die per include dazu geladen werden, (mit PHP) nicht ohne weiteres auslesen kann. Bitte korrigiert mich, wenn das so nicht stimmt.

  2. Leider muss man, damit include funktioniert, die open_basedir-Restriktion für das Include-Dir aufheben, also den Include-Path dort eintragen. Das führt leider dazu, dass man auch mit den anderen Datei-Lesefunktionen auf das Verzeichnis zugreifen kann und dann die Includes doch im Klartext bekommt.

Unter Zugrundelegung meiner Annahme zu 2. würde ich nun gerne das PHP so patchen, dass beim include-Zugriff nicht mehr das Open-Basedir geprüft wird, sondern nur noch die Include-Pfade und ob der Webserver-User (z.B. www-data) berechtigt ist, dort zu lesen.

Ist das möglich und welchen Aufwand würde es bedeuten?

Grüße
TS

  1. Moin!

    Das führt leider dazu, dass man auch mit den anderen Datei-Lesefunktionen auf das Verzeichnis zugreifen kann und dann die Includes doch im Klartext bekommt.

    Ja. Aber wenn jemand über ein Skript beliebige Dateien lesen kann, dann hast Du eh ein Problem. Wenn ich die zu öffnende Datei (wie auch immer) vom Besucher nennen lasse, dann

    1. schreibe ich selbst das Verzeichnis davor
    2. ggf. sogar die Endung
    3. verbiete nicht genehme Zeichen (lasse nur a-zA-z0-9_.- zu) und
    4. schmeisse auch Doppelpunkte und führende Punkte raus

    Wenn die Benutzer Skripte ablegen, dann verwende mod suhosin und setze die Eigentümer und Rechte passend.

    (Backen, braten und der "Königin ihr Kind holen":)

    Ist das möglich und welchen Aufwand würde es bedeuten?

    Herunterladen, patchen, "backen" und installieren. Problem: Immer wenn ein Update kommt darfst Du prüfen, ob die zu patchende Datei noch der vorherigen Version entspricht. Wenn ja kann man die auch gleich automatisch per Skript patchen, und auch dann wieder PHP "backen" und installieren...

    Wie umfassend die Änderungen sind und welche Seiteneffekte diese haben kann nicht nicht wissen. Das es nicht in 10 Minuten getan ist ahne ich aber nicht nur.

    Jörg Reinholz

  2. Tach!

    Ist das möglich und welchen Aufwand würde es bedeuten?

    Prinzipiell kann man (so gut wie) alles programmieren. Der Aufwand besteht darin, dass du C gut beherrschen solltest und auch die PHP-Quellen kennenlernen musst, um zu entscheiden, an welcher Stelle du dich einklinkst und welche Auswirkungen dein Eingriff hat. Ist vermutlich nicht ganz so einfach.

    Welches eigentliche Problem denkst du auf diese Weise lösen zu wollen?

    dedlfix.

    1. Hallo und guten Morgen,

      Welches eigentliche Problem denkst du auf diese Weise lösen zu wollen?

      Ich stelle einen Host für mehrere Anwender mit eigenen Domains zur Verfügung. Ist also im Prinzip "Shared Hosting". Die Anwender wollen nun aber gerne fertige Bazkästen und gemeinsame Kernfunktionen nutzen. Dabei sollen sie zwar Zugriff auf die gemeinsamen Funktionen haben, aber keinen Einblick in deren Innenleben.

      Wenn Include_path nun im Prinzip genauso arbeiten würde für Include, wie es open_basedir für die übrigen Dateizugriffe, mit Ausnahme davon, dass die Pfade auch der Reihe nach durchsucht werden, dann könnte die Aufgabe damit erledjgt werden.

      Grüße
      TS

      1. Tach!

        Ich stelle einen Host für mehrere Anwender mit eigenen Domains zur Verfügung. Ist also im Prinzip "Shared Hosting". Die Anwender wollen nun aber gerne fertige Bazkästen und gemeinsame Kernfunktionen nutzen. Dabei sollen sie zwar Zugriff auf die gemeinsamen Funktionen haben, aber keinen Einblick in deren Innenleben.

        Du meinst also, etwas besonders Schützenswertes geschaffen zu haben, oder etwas, von dem du nicht sicher bist, dass man darin keine Sicherheitslücken findet?

        Nun ja, es gibt Code-Vergriesgnaddler für PHP, aber nicht kostenlos, würde ich meinen (ioncube und was von Zend).

        dedlfix.

        1. Hallo und guten Morgen,

          Du meinst also, etwas besonders Schützenswertes geschaffen zu haben, oder etwas, von dem du nicht sicher bist, dass man darin keine Sicherheitslücken findet?

          Ich stelle nur die Plattform. Der Auftraggeber macht den Rest und hat entsprechende Anforderungen gestellt. Aber im Prinzip läuft es darauf hinaus. Die Geschäftsregeln und die Rechteverwaltung sollen gekapselt werden, während die Teilnehmer in ihren eigenen Bereichen machen können, was sie wollen.

          (ioncube und was von Zend).

          Hast Du da mehr Input für mich?

          Grüße
          TS

          1. Tach!

            (ioncube und was von Zend).

            Hast Du da mehr Input für mich?

            Nein, ich weiß nur, dass es von denen was gibt. Dazu muss PHP mit einem Modul erweitert werden, was mitgeliefert wird, und dann kann man in den Dateien nicht mehr viel erkennen.

            dedlfix.

          2. Moin!

            Die Geschäftsregeln und die Rechteverwaltung sollen gekapselt werden, während die Teilnehmer in ihren eigenen Bereichen machen können, was sie wollen.

            Das macht man in dem man diese ohne (File-) Zugriffsmöglichkeiten hostet und eine definierte API übers Web anbietet. Notfalls ein zweiter (Apache)Server mit eigenem Benutzer, ServerRoot, Schlüsselpaar, Zertifikat und eigenem Port.

            Jörg Reinholz

            1. Hallo und guten Morgen,

              Die Geschäftsregeln und die Rechteverwaltung sollen gekapselt werden, während die Teilnehmer in ihren eigenen Bereichen machen können, was sie wollen.

              Das macht man in dem man diese ohne (File-) Zugriffsmöglichkeiten hostet und eine definierte API übers Web anbietet. Notfalls ein zweiter (Apache)Server mit eigenem Benutzer, ServerRoot, Schlüsselpaar, Zertifikat und eigenem Port.

              Sorry, da kann ich Dir nicht folgen.

              Es sollen x Anwender in ihren Accounts PHP-Applikationen erstellen können und dafür Klassen und Funktionsbibliotheken includen dürfen, aber nicht im Klartext öffnen. Diese Module sollen den Host auch gar nicht verlassen, also scheidet eine Kompilation oder sonstige Aktion zum Unlesbar machen aus. Dann könnte man ja immer noch das "verkrumpelte" File entführen.

              Grüße
              TS

              1. Moin!

                Es sollen x Anwender in ihren Accounts PHP-Applikationen erstellen können und dafür Klassen und Funktionsbibliotheken includen dürfen, aber nicht im Klartext öffnen.

                1. Du sollst im rechten Kasten Sand haben.
                2. Du sollst im linkem Kasten nichts haben.
                3. Du sollst in beiden Kästen genau das gleiche haben.

                Bedingung 1 geht. Bedienung 2 geht auch. Natürlich ist Bedingung 3 erfüllbar.

                Nur eben maximal 2 davon auf einmal.

                Diese Module sollen den Host auch gar nicht verlassen, also scheidet eine Kompilation oder sonstige Aktion zum Unlesbar machen aus.

                Tja. Das obiges (includen:ja / lesen:nein) geht eben nicht. Wer includen können soll, der MUSS definitiv auch lesen können.

                Wenn die Module nicht gelesen werden dürfen, dann müssen die eben über ein Protokoll mit den anderen kommunizieren. Hier bietet sich HTTP durchaus an (natürlich kann man auch FIFOS nehmen...). Also "einfach" den Apache mit einer zweiten Konfiguration starten und definieren wie die Skripte der Teilnehmer mit denen auf dem zweiten Apache kommunizieren ("API").

                Google macht es vor.

                Der 2. Server (keine eigene Hardware) bekommt einen eigenen Benutzer (nicht: www-data).

                Alternative: Kein zweiter Server nur ein eigenes Verzeichnis, Kommunikation der Skripte über https (einfach) oder FIFOs (schwieriger), dafür aber mod_suhosin konfigurieren.

                Jörg Reinholz

                1. Hallo und guten Morgen,

                  Diese Module sollen den Host auch gar nicht verlassen, also scheidet eine Kompilation oder sonstige Aktion zum Unlesbar machen aus.

                  Tja. Das obiges (includen:ja / lesen:nein) geht eben nicht. Wer includen können soll, der MUSS definitiv auch lesen können.

                  Das sehe ich anders!

                  PHP wrd auf dem Webserver ausgeführt. Hierzu kann Code aus dem Reich von Domain example.org kommen und es kann Code aus dem Reich von /usr/share/php/commoncode/ kommen. Dieser Code kann vom Webserver-Benutzer zwar zur Ausführung geladen werden, aufgrund der Eigenart von PHP aber nicht durch die normalen PHP-Dateisystemfunktionen geöffnet werden. Exec & Co kann man ausschalten.

                  Vielleicht liegt das Missverständis an der üblicherweise falschen Sprechweise "include lädt den Code an die Stelle im Script...". Tut es ja gar nicht. Es lädt den Code an die Stelle im Arbeitsspeicher! Und der ist mMn mit PHP-Mitteln nicht abbildbar für den Programmierungs-Anwender.

                  Und hier hat Dedlfix ja auch Recht: Ich lasse ja ausführen. Der Interpreter ist doch schon ein entferntes Programm für mich. Der läuft ja nicht auf meinem Client, sondern eben auf dem Server.

                  Wenn ich schon etwas schlauer wäre, dann würde ich eine Extension für PHP schreiben und der Fall wäre erledigt. Die müsste dann aber jedes Mal neu eincompiliert werden, wenn sich etwas ändert. Ist auch nicht so toll!

                  Grüße
                  TS

                  1. Hallo und guten Morgen,

                    was ist eigentlich aus der Funktion
                    http://php.net/manual/en/function.dl.php
                    geworden?

                    Da steht so eine eigenartige Warnung im Manual. Ist die Funktion nun noch drin im Umfang der neuen PHP-Versionen, oder nicht?

                    Grüße
                    TS

                    1. Moin!

                      was ist eigentlich aus der Funktion
                      http://php.net/manual/en/function.dl.php
                      geworden?

                      Da steht so eine eigenartige Warnung im Manual. Ist die Funktion nun noch drin im Umfang der neuen PHP-Versionen, oder nicht?

                      Einfach zu Ende lesen:

                      5.3.0 dl() is now disabled in some SAPIs due to stability issues. The only SAPIs that allow dl() are CLI and Embed. Use the Extension Loading Directives instead.

                      Jörg Reinholz

                      1. Hallo und guten Morgen,

                        Moin!

                        was ist eigentlich aus der Funktion
                        http://php.net/manual/en/function.dl.php
                        geworden?

                        Da steht so eine eigenartige Warnung im Manual. Ist die Funktion nun noch drin im Umfang der neuen PHP-Versionen, oder nicht?

                        Einfach zu Ende lesen:

                        5.3.0 dl() is now disabled in some SAPIs due to stability issues. The only SAPIs that allow dl() are CLI and Embed. Use the Extension Loading Directives instead.

                        ...und der Link führt in die Pampa, bzw. die INI-Einstellungen einer removed function.

                        Oder habe ich an DER Stelle (Linkziel) 'was nicht gesehen?

                        Grüße
                        TS

                  2. Moin!

                    Vielleicht liegt das Missverständis an der üblicherweise falschen Sprechweise "include lädt den Code an die Stelle im Script...". Tut es ja gar nicht. Es lädt den Code an die Stelle im Arbeitsspeicher! Und der ist mMn mit PHP-Mitteln nicht abbildbar für den Programmierungs-Anwender.

                    1. Und wie kommt er da hin? Wird von einer Quelle gelesen.
                    2. Kann man ihn mit einem anderen Benutzer laden? Ja schon. Aber dann hat nur der Benutzer und dessen Prozess Zugriff auf diesem Bereich des Arbeitsspeichers ...

                    Du kann das drehen und wenden wie Du willst. Um ein Skript zu includen musst Du es lesen können. Daran geht kein Weg vorbei. Selbst wenn Du ein kaputtes OS findest, wo ein Skript mit einem Trick ohne formelle Leserechte in den Speicher geladen werden könnte, dann wäre es so kaputt dass es eben praktisch die Leserechte einräumt

                    Jörg Reinholz

                    1. Hallo und guten Morgen,

                      Vielleicht liegt das Missverständis an der üblicherweise falschen Sprechweise "include lädt den Code an die Stelle im Script...". Tut es ja gar nicht. Es lädt den Code an die Stelle im Arbeitsspeicher! Und der ist mMn mit PHP-Mitteln nicht abbildbar für den Programmierungs-Anwender.

                      1. Und wie kommt er da hin? Wird von einer Quelle gelesen.

                      A er doch nicht für den Programmieranwender in seiner Domain zugreifbar. Das wird vom PHP-Laufzeitsystem für ihn gelesen und ausgeführt, aber nicht für ihn zugänglich gemacht.

                      Ich habe allerdings noch nicht untersucht, was die Debuggingmechanismen von PHP hier eventuell liefern. Kann ich mir mit denen den Klartext einer Methode aus einer geladenen Klasse anzeigen lassen, als Quelltext liefern lassen?

                      1. Kann man ihn mit einem anderen Benutzer laden? Ja schon. Aber dann hat nur der Benutzer und dessen Prozess Zugriff auf diesem Bereich des Arbeitsspeichers ...

                      Du kann das drehen und wenden wie Du willst. Um ein Skript zu includen musst Du es lesen können.

                      Nein, nur bestimmte Funktionen meines Laufzeitsystems müssen das lesen können, in diesem Fall eben include(). Die müssen aber keine toString-Methode haben.

                      Grüße
                      TS

                      1. Moin!

                        Aber doch nicht für den Programmieranwender in seiner Domain zugreifbar. Das wird vom PHP-Laufzeitsystem für ihn gelesen und ausgeführt, aber nicht für ihn zugänglich gemacht.

                        Mann! Das "PHP-Laufzeitsystem" erbt seine Rechte vom Benutzer. Und genau deshalb kann der Benutzer nicht nur das "PHP-Laufzeitsystem" los schicken, um die Datei zu lesen, sondern auch das Programm less oder jedes andere, welches er gerade zu benutzen beliebt und das vorhanden ist.

                        Den Ausweg habe ich und Dedlfix Dir genannt. Wenn Du das Rezept nicht rausgeben willst, dann lass die Gäste nicht kochen, sondern serviere denen den fertigen Brei. Stelle also nicht Programme bzw. Skripte sondern eine Schnittstelle (API), also eine Abfragemöglichkeit und Daten zur Verfügung. Und lass die "geheimen" Programme als Dienst unter einem anderen Benutzer laufen. PHP rödelt ja auch nicht selbst in den Datenbanken rum, sondern fragt höflich beim DBMS nach, ob es vielleicht möglich wäre, diese oder jene Daten zu erhalten.

                        Jörg Reinholz

                        1. Hallo und guten Morgen,

                          Aber doch nicht für den Programmieranwender in seiner Domain zugreifbar. Das wird vom PHP-Laufzeitsystem für ihn gelesen und ausgeführt, aber nicht für ihn zugänglich gemacht.

                          Mann! Das "PHP-Laufzeitsystem" erbt seine Rechte vom Benutzer. Und genau deshalb kann der Benutzer nicht nur das "PHP-Laufzeitsystem" los schicken, um die Datei zu lesen, sondern auch das Programm less oder jedes andere, welches er gerade zu benutzen beliebt und das vorhanden ist.

                          Wie macht man das mit PHP, wenn die Shellbefehle abgeschaltet sind?

                          Grüße
                          TS

                          1. Moin!

                            Wie macht man das mit PHP, wenn die Shellbefehle abgeschaltet sind?

                            echo htmlentities(file_get_contents($datei));
                            

                            Jörg Reinholz

                            1. Moin!

                              Wie macht man das mit PHP, wenn die Shellbefehle abgeschaltet sind?

                              echo htmlentities(file_get_contents($datei));
                              

                              Schöner:

                              highlight_file ( $datei, false );
                              

                              Jörg Reinholz

                            2. Hallo und guten Morgen,

                              Moin!

                              Wie macht man das mit PHP, wenn die Shellbefehle abgeschaltet sind?

                              echo htmlentities(file_get_contents($datei));
                              

                              Jetzt willst Du mich aber ärgern, oder?

                              Ich schrieb doch ganz ausdrücklich, dass ich open_basedir nicht öffnen will für das Verzeichnis, in dem die betroffenen Includedateien liegen und icn daher include() beibringen will, wo es trotzdem zugreifen darf.

                              Grüße
                              TS

                              1. Moin!

                                Jetzt willst Du mich aber ärgern, oder?

                                Nimm das wie Du willst.

                                Ich schrieb doch ganz ausdrücklich, dass ich open_basedir nicht öffnen will für das Verzeichnis, in dem die betroffenen Includedateien lkegen und icn daher include() beibringen will, wo es trotzdem zugreifen darf.

                                Dann vergiss nicht, dass PHP so weit zu strippen, bis mir nichts mehr einfällt wie ich an die Daten komme. Ich befürchte allerdings sehr stark, dass es dann soweit seiner Funktionen beraubt ist, dass es nutzlos ist...

                                Die "gemeinen" Tricks verrate ich Dir aber erst, wenn Du meinst, fertig zu sein ...

                                Jörg Reinholz

              2. Tach!

                Es sollen x Anwender in ihren Accounts PHP-Applikationen erstellen können und dafür Klassen und Funktionsbibliotheken includen dürfen, aber nicht im Klartext öffnen.

                Warum müssen sie diesen Code selbst ausführen? Reicht nicht, dass sie jemandem sagen, was sie wollen und von dem diese Daten gereicht bekommen?

                Da sollen deine Anwender in ein Restaurant gehen und selbst kochen, aber nach einem Rezept, das sie nicht sehen dürfen. Dann mach du das Essen fertig und stell es ihnen hin.

                dedlfix.