2012-03-30 13 views
6

私は、特定のPHPスクリプトをデータベースに保存し、必要に応じてそれらを取り出して実行するブラウザアプリケーション用のシステムを作成しています。最初はexec()とpipingを使ってデータベースからスクリプトを取り出し、それらを出力したスクリプトの出力をPHPで試してみました。これは1つのユースケースで動作しますが、すべてではなく、とにかく脆いと感じるので、私はより良い方法を探しています。"php:// memory"ストリームからインクルード

私は現在、メモリ内でPHPファイルストリームを使用してこれを達成しようとしています。たとえば、

$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"; 

ただし、スクリプトの実行時には何も印刷されません。これはこの手段でも可能ですか?そうでない場合は、これを行う別の方法がありますか?私はファイルシステムにアクセスすることが遅くなると確信しているので、一時的なファイルを書かなくてもそれらから読むことを避けようとしています。 「インクルード」に提供できるURLはありますか?それで、メモリストリームをファイルのように読み取ることができますか?

eval()私は正しく覚えていれば、1行に限られているので、これを行うとは思いません。

また、「eval = include = hell」という回答はしないでください。管理者以外のユーザーは、データベースに格納されているスクリプトを書き込むためのアクセス権がありません。私は、これが私のアプリケーションのライフサイクルにわたって特別な扱いを必要としていることを知っています。

+0

マイ私は全く間違っていた。 Evalは複数の行で動作します。私もそれを試してみませんでした...それはその後動作すると仮定します。 しかし、メモリに保存されているファイルストリームについてはまだ興味があります。その部分に誰かが答えを持っていれば、感謝しています。 –

+0

ファイルを作成したくない特別な理由はありますか?ファイルシステムはファイルのデータベースです。そして、OMGはそれが危険なことをしないでください。 SQLインジェクションのバグがあったり、あなたのMySQL資格情報の取得/推測/公開を管理したりするとすぐに、管理者だけがこれらのphpファイルに書き込むことができます。insta-remote-code-execution – mensi

答えて

5

php://memory streamから読むにはstream_get_contentsを使用する必要があります。それを直接含めることはできません。

4

eval()includeは実際にはかなり同じです。したがって、eval()は複数の行で動作します。しかし、私はここでincludeを好むだろう、私はいつもより速いと思う。たぶん私は間違っている、ないアイデアです。

しかし、私はあなたのコードをデバッグすべきだと思っています。私はなぜそれがうまくいかないのか理由を見ません。 rewindポインタが必要な場合があります(コメントしています)が、最初に確認する必要があるのはthat your PHP configuration allows to include URLsです。私はその設定がURIの使用を防いでいることを知っているので、これを有効にすることができます。

また、PHPがfile_get_contentsを使用してメモリをオープンし、ダンプアウトすることができます。これはあなたにコードを与えるはずです。そうでない場合は、既に間違いをしています(巻き戻しや似たようなことはしません)。

編集:私はそこまで来ていませんでした(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)); 

これは私が見つけたものです:

  1. あなたは、 "ファイル" を閉じてはいけません。 php://memoryは一度閉じたストリームで消えてしまいます。
  2. ストリームとして$fpにアクセスする必要があります。includeのAFAIKでは使用できません。
  3. これで、ストリームリソースをファイル名にマップするストリームラッパーを作成する必要があります。
  4. これを実行したら、メモリストリームを含めることができます。
  5. とにかくチェックする必要のあるPHP設定。複数ある場合は、PHPマニュアルを参照してください。

データの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); 

にも参照してください:Include code from a PHP stream

+0

これは未定義の変数エラーを返します。 これを修正するには、 'var_dump($ thing);を' var_dump(\ $ thing);に変更してください。 –

+0

@CláudioSilva:修正されました。ヒントのためのThx。 – hakre

0

をPHPから含める方法がある場合://メモリ、この深刻な脆弱性です。多くの用途がありますが、evalは悪意のあるコードを隠すためのコードの難読化技法でかなり頻繁に使用されます。そうは言って

(。あなたは右のそれを保持している場合、すべてのツールが武器である)

、(ありがたいことに)PHPからインクルードする任意の明白な方法があるように表示されません://メモリ

関連する問題