10 Stimmen

Schließen Sie den Stream "php://memory" ein

Ich schreibe ein System für eine Browseranwendung, das einige bestimmte PHP-Skripte in einer Datenbank speichern und dann herausziehen und ausführen wird, wenn es benötigt wird. Zuerst habe ich versucht, exec() zu verwenden und die Ausgabe eines Skripts, das die Skripte aus der Datenbank holte und sie ausdruckte, an PHP weiterzuleiten. Dies hat in einem Anwendungsfall funktioniert, aber nicht in allen und fühlt sich so oder so anfällig an, also suche ich nach einem besseren Weg.

Ich versuche jetzt, dies durch die Verwendung eines PHP-Dateistreams im Speicher zu erreichen. Zum Beispiel:

$thing = <<<'TEST'

TEST;

$filename = "php://memory";

$fp = fopen($filename, "w+b");
fwrite($fp, $thing);
//rewind($fp);

fclose($fp);

include "php://memory";

Es wird jedoch nichts gedruckt, wenn das Skript ausgeführt wird. Ist dies überhaupt auf diesem Weg möglich und wenn nicht, gibt es einen anderen Weg, dies zu tun? Ich versuche zu vermeiden, temporäre Dateien schreiben und von ihnen lesen zu müssen, da der Zugriff auf das Dateisystem die Dinge verlangsamen würde. Gibt es eine URL, die ich zum "include" bereitstellen kann, damit der Speicherstrom gelesen wird, als ob es eine Datei wäre?

Ich glaube nicht, dass eval() dies tun würde, da es, wenn ich mich richtig erinnere, auf eine einzige Zeile beschränkt ist.

Bitte auch keine Antworten wie "eval = include = die Hölle". Nicht-administrative Benutzer haben keinen Zugriff, um die Skripte, die in der Datenbank gespeichert sind, zu schreiben. Ich weiß, dass dies im Lebenszyklus meiner Anwendung eine besondere Behandlung erfordert.

0 Stimmen

Mein Wort, ich lag völlig falsch. Eval funktioniert tatsächlich für mehr als eine Zeile. Ich habe es nicht einmal ausprobiert lol... also wird das funktionieren. Ich bin jedoch immer noch neugierig auf Dateiströme, die im Speicher gespeichert sind, also wäre ich dankbar, wenn jemand eine Antwort auf diesen Teil hätte.

0 Stimmen

Gibt es einen bestimmten Grund, warum du keine Dateien erstellen möchtest? Das Dateisystem ist eine Datenbank für Dateien. Und: OH MEIN GOTT, TU ES NICHT, DAS IST GEFÄHRLICH. Es spielt keine Rolle, ob nur Admins in diese PHP-Dateien schreiben können, sobald du einen SQL-Injectionsfehler hast oder jemand deine MySQL-Zugangsdaten bekommt/rät/aufdeckt -> sofortige Remote-Code-Ausführung.

6voto

pHiL Punkte 1561

Sie müssen stream_get_contents verwenden, um aus dem php://memory-Stream zu lesen. Sie können es nicht direkt einbeziehen.

6voto

hakre Punkte 184133

eval() und include sind eigentlich ziemlich gleich. So funktioniert eval() mit mehreren Zeilen - nur zur Info. Allerdings würde ich hier lieber include verwenden, ich denke immer, dass es schneller ist. Vielleicht liege ich falsch, keine Ahnung.

Ich denke jedoch, du solltest deinen Code debuggen. Ich sehe keinen per se Grund, warum es nicht funktionieren sollte. Du musst möglicherweise den Zeiger zurückschieben (du hast das kommentiert), aber das erste, was du überprüfen solltest, ist, dass deine PHP-Konfiguration das Einbinden von URLs zulässt. Ich weiß, dass diese Einstellung die Verwendung der data:// URIs verhindert, also hast du das möglicherweise aktiviert.

Du kannst auch immer versuchen, ob PHP den Speicher öffnen kann, indem du file_get_contents verwendest und ausgibst. Das sollte dir den Code geben. Wenn nicht, hast du bereits einen Fehler gemacht (zum Beispiel kein Zurückspulen oder ähnliches).

Bearbeitung: Ich bin nicht so weit gekommen (Demo):

``

Das ist, was ich herausgefunden habe:

  1. Du solltest die "Datei" nicht schließen. php://memory ist ein Stream, sobald er geschlossen ist, verschwindet er.
  2. Dann musst du auf das $fp als Stream zugreifen, was für include out of the box AFAIK nicht möglich ist.
  3. Dann müsstest du einen Stream Wrapper erstellen, der einen Stream-Ressource auf einen Dateinamen abbildet.
  4. Wenn du das gemacht hast, kannst du einen Memory Stream einbinden.
  5. Die PHP-Einstellungen, die du auf jeden Fall überprüfen musst. Es gibt mehr als eine, siehe im PHP-Handbuch nach.

Es könnte einfacher sein, den data URI zu verwenden (Demo):

`

Siehe auch: Code aus einem PHP-Stream einbinden

` ``

0 Stimmen

Dies gibt einen Fehler für eine nicht definierte Variable aus. Um es zu beheben, ändern Sie var_dump($thing); in var_dump(\$thing);

0 Stimmen

@CláudioSilva: Behoben. Danke für den Hinweis.

1voto

Xex Punkte 19

Wenn es einen Weg gibt, von php://memory einzuschließen, handelt es sich um eine ernsthafte Sicherheitslücke. Obwohl es viele Verwendungszwecke gibt, wird eval recht häufig mit Code-Verfremdungstechniken verwendet, um bösartigen Code zu verbergen.

(Jedes Werkzeug ist eine Waffe, wenn man es richtig benutzt.)

Allerdings scheint es (zum Glück) keinen offensichtlichen Weg zu geben, von php://memory einzuschließen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X