2009-03-03 35 views
1

皆さん、こんにちは皆さん、CodeIgniter PHP frameworkを使って写真共有サイトを開発しています。アイデアは、人々が自分の写真をアップロードしたり、ファイルを管理したり(サブフォルダの作成、ファイルのドラッグなど)、編集することができます(サイズ変更、回転、後で、私はいくつかの高度な機能を追加します)。ユーザーからPHPファイルマネージャを保護する

私は既にCI(Redux Authentication 2 Beta)用のサードパーティ認証ソリューションを実装していますが、JS/PHPファイルマネージャ(AjaxExplorer)を統合していますが、問題はファイルの管理(PHPのバックエンド、etc)は、ajax呼び出しからのユーザ入力をあまりにも信頼しています。あなたが見ることができるように、それは盲目的にユーザがスローどんなパス受け入れるよう

move_uploaded_file($_FILES['upload']['tmp_name'], $root.$username.$_POST['destination_dir']); 

は、明らかなセキュリティ上の懸念があります。例えば、それは、(明瞭にするために簡略化され)、このようなことをやっています! $ _POST ['destination_dir']の値として誰かが "../AnotherUser/"のようなものを送るのを見ることができます。

私の質問はユーザーが自分のデータを管理できるようにするために、ユーザーを「サンドボックス」するにはどうすればよいですか?すべての侵入試行を捕まえることを望み、入力を検証してフィルタリングするだけですか?この特定の問題に対処するために専用のライブラリ/パッケージはありますか?

私は、この問題は、ユーザーにWebブラウザを介してファイルを管理する能力を与えるプロジェクト(成熟したプロジェクト)で何らかの形で解決されなければならないと思うので、これに関するいくつかの明確なガイドラインがSQLインジェクション、XSS、CSRFなどについてはたくさんありますが)私は正しいキーワードを使用していないと思います。

答えて

6

最良の方法は、彼だけが彼自身のデータを管理することを可能にするためには「サンドボックス」ユーザー、何ですか?

ファイル名/ディレクトリ名を任意に指定できますが、サーバー側のファイルシステムでは使用しないでください。その代わりに、プライマリキーを使用してデータベースにパス名を書き出し、プライマリキーをフラットなストレージディレクトリ(または必要に応じてデータベース内のBLOB)として '34256.dat'のようなファイル名として使用します。次に、ダウンロードスクリプトまたはURL書き換えを実行して、目的のファイル名がURLに表示されるようにします。

着信ファイル名のサニタイズは、ハードです。 「..」を検出するのは始まりにすぎません。ファイル名が長すぎます。あまりにも短いファイル名。先頭と末尾のドットの組み合わせ。先頭と末尾の空白の組み合わせ。異なるプラットフォームの異なるディレクトリセパレータ。プラットフォームによっては無効な文字。制御文字; Unicode文字とそれを扱う環境固有の方法ADS;あなたのウェブサーバーにとって特別なファイル名( '.htaccess')または拡張子( '.php'、 '.cgi') Windowsの予約済みファイル名...

さまざまなプラットフォームでファイルパスルールの面白い小さな欠点を追跡したり、それを忘れたりデータベースを使用したりすることができます。

+0

答えをbobinceさんにありがとう!これは良い解決策ですが、ファイルの単純なバックアップを行うと、名前付けスキームを逆にするスクリプトが最初に実行されることを意味するため、データの移植性に懸念があります。データベースが侵害されたり破損したりすると、 dirのツリー構造。 – lima

+0

良い解決策。 @fandelost、次にデータベースとファイルの両方をバックアップすることを確認してください –

+0

私はとても長い時間がかかりました。私は最終的に "AjaxExplorer"を辞任し、自分のファイル管理ソリューションを構築しました.Bobinceの助言に基づいて、ファイルに関連するすべてを保存するデータベースを使用していましたが、Webルートの外にアップロードした後には触れませんでした。私はまた、それぞれの名前のフィールドを制限された文字セットに制限しました。そして、私は入れ子にされたフォルダを使用しません。代わりに単一のレベルのグループ化を使用します。 – lima

0

私はあなたのdestination_dirがどのように見えるか分かりませんが、私はディレクトリキーを割り当てて、そのキーに基づいてディレクトリを取得していると思いました。例:

//$_POST['destination_dir'] = '4hg43h5g453j45b3'; 
*_query('SELECT dir FROM destinations WHERE key = ? LIMIT 1'); //etc. 

ただし、事前にキーを事前に定義する必要があります。 md5/sha1と入力し、それをdestination_dirとして使用し、関連するラベルとともにデータベースにそのキーを格納することもできます。

0

私が知っているライブラリはありません。
しかし、特定の例では、文字列からすべてのスラッシュとドットを取り除き、最後にスラッシュを追加すると、ユーザーはフォルダを変更できなくなります。

$destdir = str_replace(array('.', '/', '\\'), '', $_POST['destination_dir']); 
$destdir .= "/"; 
+0

すべての無効な文字列は、サーバーのルートフォルダにマップされます。 – bobince

+0

答えがありがとう、しかし、AFAIKのドット、スラッシュ、バックスラッシュは、少なくとも* NIXの世界では、フォルダの命名に使用できる文字です。 – lima

+0

私はパスを前に置くことができるので、あまり真実ではありませんが、とにかくこのソリューションを使用することはありません。 – lima

関連する問題