2012-03-30 4 views
6

J'écris un système pour une application de navigateur qui va stocker certains scripts php particuliers dans une base de données, puis les retirer et les exécuter en cas de besoin. Au début, j'ai essayé d'utiliser exec() et piping pour php la sortie d'un script qui a sorti les scripts de la base de données et les a imprimés. Cela a fonctionné dans un cas d'utilisation, mais pas tous, et se sent fragile de toute façon, donc je cherche un meilleur moyen.Inclure du flux "php: // memory"

Je tente maintenant d'accomplir ceci en utilisant un flux de fichier PHP en mémoire. Par exemple:

$thing = <<<'TEST' 
<?php 

$thing = array(); 

print "Testing code in here."; 
var_dump($thing); 

?> 
TEST; 

$filename = "php://memory"; 

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

fclose($fp); 

include "php://memory"; 

Cependant, rien n'est imprimé lors de l'exécution du script. Est-ce possible même par ce moyen, et sinon, y a-t-il une autre façon de le faire? J'essaie d'éviter d'avoir à écrire des fichiers temporaires et de les lire, car je suis sûr que l'accès au système de fichiers ralentirait les choses. Y at-il une URL que je peux fournir à "include" pour qu'il lise le flux de mémoire comme s'il s'agissait d'un fichier?

Je ne pense pas que eval() ferait cela, car, si je me souviens bien, c'est limité à une seule ligne.

En outre, s'il vous plaît pas de réponses "eval = include = hell". Les utilisateurs non-administrateurs n'ont pas accès à l'écriture des scripts stockés dans la base de données, je sais que cela nécessite un traitement spécial tout au long du cycle de vie de mon application.

+0

Mon mot, j'avais totalement tort. Eval fonctionne pour plus d'une ligne. Je ne l'ai même pas essayé lol ... suppose que ça marchera alors. Cependant, je suis toujours curieux au sujet des flux de fichiers stockés dans la mémoire, donc si quelqu'un a une réponse à cette partie, je serais reconnaissant. –

+0

Y a-t-il une raison particulière pour laquelle vous ne voulez pas créer de fichiers? Le système de fichiers est une base de données pour les fichiers. Et: OMG NE FAITES PAS CELA EST DANGEREUX. Peu importe si seuls les administrateurs peuvent écrire dans ces fichiers php, dès que vous avez un bug d'injection SQL ou que quelqu'un parvient à obtenir/deviner/révéler vos informations d'identification MySQL -> insta-remote-code-execution. – mensi

Répondre

5

Vous devez utiliser stream_get_contents pour lire le php://memory stream. Vous ne pouvez pas l'inclure directement.

4

eval() et include sont en fait assez similaires. Donc, eval() fonctionne avec plusieurs lignes - juste FYI. Cependant, je préférerais include ici, je pense toujours que c'est plus rapide. Peut-être que je me trompe, pas d'idée.

Cependant, je pense que vous devriez déboguer votre code, je ne vois pas de raison pourquoi il ne devrait pas fonctionner. Vous devrez peut-être rewind le pointeur (vous avez commenté cela), mais ce que vous devriez vérifier de première main est, that your PHP configuration allows to include URLs. Je sais que ce paramètre empêche l'utilisation de l'URI data://, donc vous pouvez avoir cette activé.

Aussi, vous pouvez toujours essayer si PHP peut ouvrir la mémoire en utilisant file_get_contents et le dumping. Cela devrait vous donner le code. Si ce n'est pas le cas, vous avez déjà fait une erreur (par exemple, ne pas revenir en arrière ou quelque chose de similaire).

Edit: Je suis venu pas loin (demo):

<?php 
/** 
* Include from “php://memory” stream 
* @link https://stackoverflow.com/q/9944867/367456 
*/ 

$thing = <<<TEST 
<?php 
\$thing = array(); 
print "Testing code in here."; 
var_dump(\$thing); 
TEST; 

$filename = "php://memory"; 

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

var_dump(stream_get_contents($fp)); 

C'est ce que j'ai découvert:

  1. Vous ne devez pas fermer le "fichier". php://memory est un flux une fois fermé, il va disparaître.
  2. Vous devez accéder au $fp comme flux que, ce qui n'est pas possible pour include prêt à l'emploi AFAIK.
  3. Vous devez ensuite créer un wrapper de flux qui mappe une ressource de flux sur un nom de fichier.
  4. Lorsque vous avez fait cela, vous pouvez inclure un flux de mémoire.
  5. Les paramètres PHP que vous devez vérifier quand même. Il y en a plus d'un, consultez le manuel PHP.

Il pourrait être plus facile à utiliser les données URI (demo):

<?php 
/** 
* Include from “php://memory” stream 
* @link https://stackoverflow.com/q/9944867/367456 
*/ 

$thing = <<<TEST 
<?php 
\$thing = array(); 
print "Testing code in here."; 
var_dump(\$thing); 
TEST; 

include 'data://text/plain;,'. urlencode($thing); 

Voir aussi: Include code from a PHP stream

+0

Cela donne une erreur variable indéfinie. Pour résoudre ce problème, changez 'var_dump ($ thing);' en 'var_dump (\ $ thing);' –

+0

@ CláudioSilva: Corrigé. Merci pour l'indice. – hakre

0

S'il y a un moyen d'inclure de php: // mémoire alors ce est une vulnérabilité sérieuse. Bien qu'il ait de nombreuses utilisations, eval est souvent utilisé avec des techniques d'obscurcissement de code pour cacher du code malveillant.

(Chaque outil est une arme si vous tenez à droite.)

Cela dit, il y a (heureusement) ne semble pas être une façon évidente d'inclure de php: // mémoire