mathefritz: php include, Ordnertiefe

ich möchte, in php, eine include Datei verwenden, die viele Ordner höher als die Aufrufende gehostet ist, aber weiter als ../../../DateiName.php scheint es nicht zu funktionieren;

Legt das der Hoster fest oder ist da noch ein vertrackte Fehler bei mir?

  1. Hallo mathefritz,

    Include mit Pfadangabe sollte relativ zum einbettenden Script aufgelöst werden, und den PHP include_path ignorieren.

    Möglicher Layer-8 Fehler: Bist Du über den Ordner, in dem dein Web beginnt, irrtümlich hinausmarschiert und hast dort kein Leserecht?

    Ich probier's gleich mal selber.

    Rolf

    --
    Dosen sind silbern
    1. Hallo Ingrid,

      Ergbnis ist: Funktioniert auch mit 5 Stufen, solange ich keinen Gefängnisausbruch versuche. Natürlich habe ich auf meinem Webspace getestet...

      Mal angenommen, dein Hoster hätte so eine Verzeichnisstruktur gebaut:

      webs/
         userA
            aWeb/
         userB/
            bWeb/
         mathefritz/
            mathe/
               area51/
                  bay7/
                     test.php
      

      Wenn test.php (im bay7-Ordner) auf ../../../huhu.inc zugreift, sucht es diese Datei im mathefritz Ordner. Das darf es.

      Probiert es das aber mit einem ../ mehr, dann würde es auf den webs-Ordner zugreifen. Wenn man das "Jail-in" Modell von TS verfolgt, würdest Du damit versuchen, aus deiner Zellensuite namens "mathefritz" in den Gang davor zu laufen. Da sind aber Gitter, damit Du nicht irrtümlich an "user a" einen Kassiber übergibst, oder gar deinen Vorrat an Gras dort versteckst.

      Rolf

      --
      Dosen sind silbern
  2. Hello,

    Legt das der Hoster fest oder ist da noch ein vertrackte Fehler bei mir?

    Du willst vermutlich nicht wissen OB der Hoster das beim shared Hosting festlegt, sonder WIE er das macht und wie Du feststellen kannst, WAS festgelegt ist?

    DASS er das festlegt, auf welche Verzeichnisse Du zugreifen kannst, darauf kannst Du dich verlassen, wenn der Hoster bei Trost ist.

    Wie er das machen kann, hängt von unterschiedlichen Faktoren ab:

    • PHP als Modul oder als (Fast-)CGI
    • Welche Apache-Version (wenn Apache verwendet wird) Ab Apache 2.4 kann pro Virtual Host ein eigener VHost-User festgelegt werden, unter dem die Scripte auch bei der Modulversion laufen. Da kann man dann bequem per (Linux-)Rechtesystem einen Behälter festlegen, in dem sich der VHost austoben darf.
    • Bei PHP als CGI wird meistens ein "Jail" für den Kunden angelegt, aus dem er nicht herauskommen sollte.

    Liebe Grüße
    Tom S.

    --
    Es gibt nichts Gutes, außer man tut es!
    Das Leben selbst ist der Sinn.
    1. Danke, geht allerdings weit über meinen Horizont.

      Es handelt sich um einen kostenlosen Account bei lima-city.de ; werd wohl am besten deren Support fragen müssen .

    2. im chat bei lima-city.de meine man eigentl dürften schon 3 Stufen misslingen wegen der
      openbasedir-Restriktion
      und daß dumme ist daß sich auch kein Link setzen läßt, was ja das vernüftigste wäre ( mit dem Linux Dateimanager Dolphin kann ich per ftp direkt auf dem Host arbeiten,
      aber "drag" einer Datei in einen anderen Ordner, und dort "link" wählen wird verweigrt.
      Ist
      es prinzipiell unmöglich, oder ist Script dafür denkbar ? )

      1. Hallo mathefritz,

        deine Hinweise sind - zumindest für mich - recht verworren. Welchen Wert hat denn bei Dir open_basedir in der php.ini (kann man im Zweifelsfall mit ini_get() ermitteln und ausgeben), und willst Du tatsächlich aus diesem Käfig hinaus?

        Wenn ja - warum eigentlich? Und: wohin greifst Du mit deinem Pfad: Garantiert noch in deinen Webspace hinein? Wenn ja: Wieso setzt lima city dann eine open_basedir Restriktion?

        Links - hm, braucht man dafür nicht shell-Zugriff? Wüsste nicht, dass das FTP Protokoll das hergibt.

        Rolf

        --
        Dosen sind silbern
        1. Hallo rolf, danke; meintest Du

          <?php
           echo ini_get(open_basedir);
          ?>
          
          

          das Ergebnis ist /tmp:/home/webpages/tmp:/dev/urandom:/etc/ssl/certs:/home/webpages/lima-city/flh/flh.lima-city.de
          aber wohl weniger hilfreich; die inlude Datei befindet sich 8 Ebenen über dem Aufrufer; ; symlink(...) hab ich erfolglos probiert; glaube nicht, daß da ftp ins spiel kommt; ist doch serverinterne operation?
          scheint aber trotzdem unmöglich, weder "heraufholen" noch "herunterholen im Ordnerbaum

          1. Moin Fritz,

            wo liegt denn deine aufrufende Datei und wo die einzubettende? Da wir das open_basedir haben, wäre jetzt noch eine Info zu deiner Ordnerstruktur interessant um deine Frage zu beantworten.

            Viele Grüße
            Robert

          2. Hallo mathefritz,

            das ist eine Liste von mehreren Verzeichnisnissen, in denen Du Dich tummeln darfst.

            • /tmp
            • /home/webpages/tmp
            • /dev/urandom
            • /etc/ssl/certs
            • /home/webpages/lima-city/flh/flh.lima-city.de

            Wenn Du ACHT Ebenen hochwillst, solltest Du uns wirklich mal die absoluten Pfade verraten, wo die includende und wo die includete Datei eigentlich liegen. Hast Du in flh.lima-city.de eine derart tiefe Schachtelung?

            Rolf

  3. ich möchte, in php, eine include Datei verwenden, die viele Ordner höher als die Aufrufende gehostet ist, aber weiter als ../../../DateiName.php scheint es nicht zu funktionieren;

    Legt das der Hoster fest oder ist da noch ein vertrackte Fehler bei mir?

    Ja, Dein Fehler: Er ist systematischer Natur. Gar nicht erst anfangen, besser ist es, den Include-Path zu setzen oder ausnahmsweise mit einer absoluten Pfadangabe zu arbeiten. MfG

    1. Danke;
      ok, folgendes sei, zu Demozwecken,

      <?php 
      exho "das wollte ich sehen";
      ?>
      

      die von include gerufene Datei GetIphT.php, und 8 Ordnerebenen tiefer

      <?php 
      echo(">" . set_include_path( get_include_path() . PATH_SEPARATOR . "../../../../../../../../") . "<<br>" );
      echo(">" . get_include_path()  . "<<br>" );
      include "GetIphT.php";
      echo "include sollte gelaufen sein, vor dieser Zeile 'das wollte ich sehen' anzeigen";
      ?>
      
      

      die rufende. Leider klappt es nicht.

      1. set_include_path( get_include_path() . PATH_SEPARATOR . "../../../../../../../../")

        Nein, so machen wir das ganz bestimmt nicht. Setze in Dein include /x/y/z.php bitte mal eine absolute Pfadangabe und dann schauen wir mal weiter. Tipp: Prüfe den Rückgabewert von include. MfG

        1. Danke;
          aber was wäre denn der absolute Includepfad
          wenn die IncludeDatei
          in
          http://flh.lima-city.de/xx/yy/ liegt bzw
          der ftp-Pfad ein weiteres flh.lima-city.de/ zu Beginn erfordert?
          im
          Manual steht nichts über einen Rückgabewert von include.

          1. hi,

            aber was wäre denn der absolute Includepfad
            wenn die IncludeDatei
            in
            http://flh.lima-city.de/xx/yy/ liegt

            Das vermittelt die Umgebungsvariable DOCUMENT_ROOT. Ruf mal die Funktion phpinfo() auf, die zeigt Dir das. MfG

          2. Hallo mathefritz,

            Danke;
            wenn die IncludeDatei in http://flh.lima-city.de/xx/yy/ liegt

            Guck in deine open_basedir Angabe. Wenn man annimmt, dass dein Web-Root genau so heißt wie die URL, ist es der letzte Eintrag darin. Demnach wäre der absolute Pfad in deinem Beispiel /home/webpages/lima-city/flh/flh.lima-city.de/xx/yy.

            Alternativ könntest Du auch $_SERVER['SCRIPT_FILENAME'] oder $_SERVER['DOCUMENT_ROOT'] auslesen und mit echo ausgeben.

            So. Und nun sag's uns endlich, bevor wir den Wurm mit der Hilti aus deiner Nase bohren müssen: Wie lautet der absolute Pfad von Includender und includeter Datei?!??!!!11!!elf!

            Im Manual steht nichts über einen Rückgabewert von include.

            Doch. Unter der Sicherheitswarnung. FALSE bei Fehler, 1 bei Erfolg - es sei denn du hast ein return-Statement in deinem Include, das bekommt Vorrang.

            Rolf

            1. Danke; (verbrochen habe ich von den folgenden Bezeichnungen nur flh, GetIph.php,
              . . . . $ir, KomZentral.php . . . .)
              START MIT
              https://flh.lima-city.de/Zentrale/KomandoZentrale/structure%20de%20service%20-%20Kopie/1Negotium/2Mittere/3PraetiumInfamis/4Confirmare/Lingua/Domesticus/GetIph.php
              INHALT VON GetIph.php

              <?php 
              echo ">" . set_include_path('/home/webpages/lima-city/flh/flh.lima-city.de/Zentrale/KommandoZentrale') . '<<br>';
              $ir = include "KomZentral.php";
              var_dump( $ir );
              echo "<br>include sollte gelaufen sein, vor dieser Zeile 'das wollte ich sehen' anzeigen";
              ?>
              

              IHNHALT VON KomZentral.php

              <?php 
              echo "das wollte ich sehen";
              ?>
              

              ERGEBNIS

              .<
              bool(false)
              include sollte gelaufen sein, vor dieser Zeile 'das wollte ich sehen' anzeigen

              der Pfad stimm also wohl nicht.

              1. Moin Fritz,

                echo ">" . set_include_path('/home/webpages/lima-city/flh/flh.lima-city.de/Zentrale/KommandoZentrale') . '<<br>';
                

                ERGEBNIS

                .<

                Das heißt also, dass . der Rückgabewert von set_include_path ist. Gibt dir das nicht zu denken?

                Viele Grüße
                Robert

                1. Danke;
                  oh weh, schon zuviel auf den Bildschirm gestarrt und Parkinsonzittrig; mm ist halt nicht immer Wohlgeschmack.☔️

                  bleibt der Pfad nun eigentlich auch gültig wenn eine neue Seite auf demselben Hoster aufgerufen wird?
                  Und
                  daß unbepfadete Dateizugriffe aus dem indludetem Code den Ordner meinen in dem der Includeaufruf erfolgt ist wohl selbstverständlich.

                  1. Moin Fritz,

                    oh weh, schon zuviel auf den Bildschirm gestarrt und Parkinsonzittrig; mm ist halt nicht immer Wohlgeschmack.☔️

                    Oh 😕

                    bleibt der Pfad nun eigentlich auch gültig wenn eine neue Seite auf demselben Hoster aufgerufen wird?

                    Die Doku sagt nein. Wenn du das open basedir global verändern willst, musst du PHP entsprechend konfigurieren.

                    Interessant ist eigentlich, dass set_include_path nur den Wert . zurückgibt, während ini_get('open_basedir') etwas Anderes zurückgibt.

                    Und daß unbepfadete Dateizugriffe aus dem indludetem Code den Ordner meinen in dem der Includeaufruf erfolgt ist wohl selbstverständlich.

                    Das scheint mir aber nicht das eigentliche Problem zu sein. Schalte mal Warnings an oder verwende require statt http://de2.php.net/manual/de/function.include.php um die Fehlermeldung zu erhalten, was falsch läuft.

                    Viele Grüße
                    Robert

                    1. Hallo Mathefritz,

                      das eigentliche Problem scheint zu sein, dass es die zu includende PHP Datei nicht gibt.

                      Aufruf von https://flh.lima-city.de/Zentrale/KomandoZentrale/KomZentral.php liefert HTTP 404

                      Ein weiteres Problem ist, dass Du „KommandoZentrale“ in deinem set_include_path Aufruf mit zwei „m“ geschrieben hast, der Ordner heißt aber „KomandoZentrale“ mit einem „m“. Das musst Du erstmal konsolidieren.

                      set_include_path wirkt übrigens nur für die Dauer des aktuellen Scripts (wobei ich an Hand der Doku nicht so genau verstehe, ob ein set_include_path, das in einer includeten Datei ausgeführt wird, auch noch wirkt nachdem der include durchgeführt wurde. "Dauer des aktuellen Scripts" würde das verneinen - andererseits wird die includete Datei ja Teil des Includers. Für nachfolgende Web-Requests wirkt es jedenfalls definitiv nicht mehr.

                      Auf der PHP Dokuseite für set_include_path steht übrigens noch, dass set_include_path ggf. nicht wirkt, wenn der Apache einen include_path vorgeben würde. Ob das hier auch zutrifft, weiß ich nicht - zunächst mal solltest Du feststellen, warum der Versuch schiefgeht, die zu includende Datei per Brauser direkt aufzurufen. Oder hast du das per .htaccess verhindert?

                      Rolf

                      --
                      Dosen sind silbern
                      1. Tach!

                        set_include_path wirkt übrigens nur für die Dauer des aktuellen Scripts (wobei ich an Hand der Doku nicht so genau verstehe, ob ein set_include_path, das in einer includeten Datei ausgeführt wird, auch noch wirkt nachdem der include durchgeführt wurde. "Dauer des aktuellen Scripts" würde das verneinen - andererseits wird die includete Datei ja Teil des Includers.

                        Mit Script ist hier der Request gemeint. Es gibt in PHP meines Wissens nichts, das Dateien als Grenzen hat und dann wieder zurückgesetzt wird.

                        dedlfix.

                    2. verver...fcht
                      aufeinmal funktioniert was gestern schon klappte

                      <?php
                      $fnam = "Home1BesucherZaehler.html";
                      echo $_SERVER['DOCUMENT_ROOT'] . '/Zentrale/KomandoZentrale',"<br>";
                      exit( set_include_path('/home/webpages/lima-city/flh/flh.lima-city.de/Zentrale/KomandoZentrale') );
                      ?>
                      

                      wieder nicht; der set_include_path liefert wieder nur ".",
                      obwohl der Pathpart bis ".de" mit dem des $_SERVER Zugriff übereinstimmt.
                      auch nur "." kommt mit

                        $e = set_include_path("/home/webpages/lima-city/flh/flh.lima-city.de");
                      var_dump($e);
                      

                      Verzeifelt
                      Fritz

                      1. Tach!

                        der set_include_path liefert wieder nur ".", obwohl der Pathpart bis ".de" mit dem des $_SERVER Zugriff übereinstimmt.

                        Beschreibung lesen! Die Funktion liefert das, was vorher eingestellt war, nicht das was nun eingestellt ist.

                        dedlfix.

                      2. autsch, das set_include_path den bisherigen zurückgibt hatte ich vergessen, aber der include selbst klappte doch nicht.
                        edit:
                        ok läuft wieder . seltsam .

                      3. Hallo mathefritz,

                        (Edit: Hatte den laufenden Edit eine Weile liegen lassen müssen, ihr zwei habt mich überholt :) )

                        set_include_path(...) liefert Dir nicht zurück, was es eingestellt hat, sondern was vorher eingestellt WAR - vermutlich deshalb, damit Du den alten Include-Path bei Bedarf restaurieren kannst, ohne vorher get_include_path() aufgerufen zu haben.

                        Es ist übrigens deutlich besser, $_SERVER['DOCUMENT_ROOT'] . '/Zentrale/KomandoZentrale' statt den absoluten Pfad an set_include_path zu übergeben. Wenn Du den absoluten Pfad einträgst und lima-city auf einmal meint, die Webs nicht mehr unter /home/webpages/lima-city, sondern unter /webs/reseller/lima-city zu hosten (oder sonst was), dann fällst Du auf die Nase. DOCUMENT_ROOT bleibt dagegen unverändert die Wurzel Deines Übels - äh - deines Webs.

                        Übrigens ist es so, dass set_include_path in der Form, wie Du es aufrufst, ein weiteres Problem bergen KANN: existierende include_path Einstellungen werden überschrieben. Das ist in deinem Fall kein Problem, weil der alte Wert "." ist (=aktuelles Verzeichnis), und dort sucht PHP sowieso nach includes. Aber im Allgemeinen sollte man den Include-Path nicht ersetzen, sondern erweitern. Das kannst Du das so tun:

                        set_include_path(get_include_path() . 
                                         PATH_SEPARATOR . 
                                         $_SERVER['DOCUMENT_ROOT'] . '/Zentrale/KomandoZentrale');
                        

                        PATH_SEPARATOR zu verwenden ist wichtig, weil das betriebssystemabhängig ist (';' unter Windows und ':' unter Linux).

                        Rolf

                        --
                        Dosen sind silbern
              2. Der Punkt den Du da siehst >.< wird von echo ausgegeben. Setz doch mal den absoluten Pfad mit der Datei direkt in den include Aufruf, anstatt am include- Path herumzudoktern. Also wenn Du schon nicht weißt was Du da überhaupt tust. Was sagt denn nun phpinfo() bezüglich DOCUMENT_ROOT? Wenn Du Dein FTP Programm aufrufst musst Du Doch so langsam mal merken wo Du da rauskommst, da gibts doch bestimmt ein paar Dateinamen die Dir bekannt vorkommen könnten.

                MfG

      2. Moin Fritz,

        exho "das wollte ich sehen";
        

        Wenn du keine Variableninterpolation oder Escapesequenzen hast, kannst du auch die einfachen Anführungszeichen verwenden. Aber was macht denn dein exho-Konstrukt?

        echo(">" . set_include_path( get_include_path() . PATH_SEPARATOR . "../../../../../../../../") . "<<br>" );
        echo(">" . get_include_path()  . "<<br>" );
        include "GetIphT.php";
        echo "include sollte gelaufen sein, vor dieser Zeile 'das wollte ich sehen' anzeigen";
        

        Also neben der Ausgabe des nicht HTML-gerechten > (du meinst vermutlich &gt;) fällt mir sofort auf, dass der Rückgabewert von set_include_path nicht geprüft wird. Was gibt dir denn die Funktion zurück? Und wie sieht deine Ordnerstruktur aus?

        echo ist in PHP übrigens keine Funktion, sondern ein Sprachkonstrukt, das heißt, dass du die Ausgabe nicht erst aneinander hängen musst. Das geht also auch:

        echo '&gt;', set_include_path( get_include_path() .), '<br>';
        

        Was heißt das konkret:

        Leider klappt es nicht.

        Gibt es eine Fehlermeldung?

        Viele Grüße
        Robert

        1. Danke Robert;
          exho ist natürlich ein Tippfehler, dessen Korrektur aber nichts half . Fehlermeldungen gabs keine.
          Sorry wenn ich nun nicht ausführlicher antworte, sieh Antwort an pl von 13:06

          1. Moin Fritz,

            du kannst Antworten verlinken, auch wenn du meine Frage, was set_include_path zurückliefert oder wie deine lokale Ordnerstruktur genau aussieht, immer noch nicht beantwortet hast.

            Viele Grüße
            Robert

        2. Hallo Robert B.,

          Also neben der Ausgabe des nicht HTML-gerechten > (du meinst vermutlich &gt;)

          > braucht in HTML nicht als &gt; geschrieben zu werden. Lediglich < und &, letzteres auch nur, wenn es nicht in Leerzeichen eingeschlossen ist, brauchen eine Maskierung.

          Bis demnächst
          Matthias

          --
          Rosen sind rot.
      3. Tach!

        <?php 
        echo(">" . set_include_path( get_include_path() . PATH_SEPARATOR . "../../../../../../../../") . "<<br>" );
        

        Es ist nicht die Aufgabe des Include-Path, eine relative Angabe beim Dateinamen durch eine ebensolche an anderer Stelle zu ersetzen. Damit ist nichts gewonnen. Vielmehr setzt man den Include-Pfad auf einen absoluten Wert, der dann wirken kann, egal wieviele Ebenen tiefer oder wie weit daneben man sich befindet.

        Leider klappt es nicht.

        Wenn irgendwas nicht klappt, dann ist es entweder ein logischer Fehler oder es gibt Meldungen von PHP, oder beides. Die PHP-Meldungen sollte man sich während der Entwicklung (nicht aber im Produktivbetrieb) immer ausgeben lassen. Dazu setzt man das error_reporting auf E_ALL und display_errors auf on. Am besten macht man das in der globalen Konfiguration und vergewissert sich mit phpinfo(), ob die Einstellungen auch wirken und nicht durch andere Konfigurationen überschrieben wurden.

        dedlfix.