Jens Schärer: Sandbox implementieren?

Hallo,

ich bin grade dabei eine Art Template-Engine zu schreiben. Diese selbst soll PHP als Sprache verwenden, sprich: ich will in den Templates PHP-Code verwenden können. Die Engine wird nur Intern genutzt, daher gibts da auch keine Sicherheitsbedenken demgegenüber.
Dennoch soll der in den Templates enthaltene PHP-Code nicht auf die darüberliegenden Klassen zugreifen können, also komplett unabhängig von der umgebenden Anwendung sein und eigenständig ausgeführt werden. Wie kann ich sowas realisieren?

Mfg,
Jens

  1. Dennoch soll der in den Templates enthaltene PHP-Code nicht auf die darüberliegenden Klassen zugreifen können, also komplett unabhängig von der umgebenden Anwendung sein und eigenständig ausgeführt werden. Wie kann ich sowas realisieren?

    Wie willst (oder würdest) du denn die Engine derzeit realisieren, ohne diese Forderung?

    1. Dennoch soll der in den Templates enthaltene PHP-Code nicht auf die darüberliegenden Klassen zugreifen können, also komplett unabhängig von der umgebenden Anwendung sein und eigenständig ausgeführt werden. Wie kann ich sowas realisieren?

      Wie willst (oder würdest) du denn die Engine derzeit realisieren, ohne diese Forderung?

      Die Templates mit eval() ausführen, nachdem ich vorher Template-Engine-eigene Funktionen auf die Files angewendet hab (was auch schon funktioniert). Nur wird in Blöcken wie <?php {Code} ?> auch der Zugriff auf die umgebende Klasse ermöglicht, dies soll eben NICHT möglich sein.

      Gruß,
      Jens

      1. Die Templates mit eval() ausführen, nachdem ich vorher Template-Engine-eigene Funktionen auf die Files angewendet hab (was auch schon funktioniert). Nur wird in Blöcken wie <?php {Code} ?> auch der Zugriff auf die umgebende Klasse ermöglicht, dies soll eben NICHT möglich sein.

        Dann ist eval, wie zu erwarten war, die falsche Funktion für deinen Ansatz.

        Was bleibt dann noch, wenn du dein Template-Skript, welches sich verhalten soll, als wäre es komplett isoliert ausgeführt, ausführen willst?

        Mein Tipp: Du mußt es komplett isoliert ausführen, in einem separaten Prozess.

        Separate Prozesse kriegst du mit PHP aber nur hin, wenn du eine eigenständige PHP-Datei hast, die du dem PHP-Interpreter übergibst. Dessen Output kannst du dann capturen.

        1. hi,

          Dann ist eval, wie zu erwarten war, die falsche Funktion für deinen Ansatz.

          Was bleibt dann noch, wenn du dein Template-Skript, welches sich verhalten soll, als wäre es komplett isoliert ausgeführt, ausführen willst?

          Tja, disable_functions und disable_classes sind leider nur in der php.ini kofigurierbar - sonst hätte man die auch vor einem evil eval setzen können ...

          Einen Zugriff auf bestehende Objektinstanzen und Variablen könnte man ja evtl. noch hinbekommen, in dem man das Ganze in einen Funktionskontext bringt - Zugriff per Schlüsselwort global oder über $GLOBALS müsste man dann noch unterbinden, in dem man ggf. nach diesen Schlüsselworten im auszuführenden Code sucht ...

          Alles in allem finde ich diesen Ansatz aber auch wenig erfolgversprechend, bzw. zu löchrig, um sich darauf zu verlassen.

          gruß,
          wahsaga

          --
          /voodoo.css:
          #GeorgeWBush { position:absolute; bottom:-6ft; }
          1. hi,

            Einen Zugriff auf bestehende Objektinstanzen und Variablen könnte man ja evtl. noch hinbekommen

            Nicht hinbekommen, sondern verhindern.

            gruß,
            wahsaga

            --
            /voodoo.css:
            #GeorgeWBush { position:absolute; bottom:-6ft; }
  2. echo $begrüßung;

    [...] Template-Engine [...] PHP als Sprache [...]
    Dennoch soll der in den Templates enthaltene PHP-Code nicht auf die darüberliegenden Klassen zugreifen können, also komplett unabhängig von der umgebenden Anwendung sein und eigenständig ausgeführt werden. Wie kann ich sowas realisieren?

    Komplett abschotten ist sicherlich nicht möglich, wenn man keinen zweiten Prozess für die Template-Engine instantiieren will. Aber ist das so rigoros denn überhaupt nötig? Ich finde das, was die Zend_View-Komponente vom Zend Framework macht, schon eine recht brauchbare Lösung.

    Eine abstrakte Klasse (Zend_View_Abstract) deklariert alle Funktionen und Eigenschaften als privat, die das Template nicht aufrufen darf. Die Eigenschaften, auf die das Template zugreifen soll, werden als public der Instanz hinzugefügt, bzw. über __get() verfügbar gemacht. Das von Zend_View_Abstract abgeleitete Zend_View hat nur die Methode zum Ausführen des Templates, und damit kann das Template nur auf die freigegebenen Variablen und public-Funktionen zugreifen (und auf das, was sonst noch so global verfügbar ist. Und das kann man bei konsequenter OOP auf recht wenig bis gar nichts beschränken.)

    echo "$verabschiedung $name";