2012-09-07 7 views
7

私は(a scriptとStackの助けを借りて、友人の助けを借りて、私はPHPについてほとんど知りません)人々が写真をアップロードできる地方の非営利出版物のための簡単なページを作成しました。PHP画像アップロードスクリプトを悪用から保護するにはどうすればよいですか?

私は(無知の根拠からではなく、意図的な過失)セキュリティとは大きくないが、私はこのページを保護するには、次の手順を撮影した:

PHPスクリプトのみの.jpgを受け入れるように設定されています、.png、.tifファイルをアップロードします。
•フォームコンテンツを保存するサブフォルダにはアクセス権が700、アップロードされた写真を保存するサブフォルダには700に設定されたアクセス許可があります。文書によると、私のホストは唯一の.phpファイルを.phpのように実行することを確認するために、以下の構成を有する
•:

<FilesMatch \.php$> 
    SetHandler php52-fcgi 
</FilesMatch> 

私は関連で.htaccessファイルに置く(メインにして、コンテンツを保存)しました。•フォルダ:一晩

RemoveHandler .php 
RemoveHandler .inc 
RemoveHandler .pl 
RemoveHandler .cgi 
RemoveHandler .py 
RemoveHandler .fcgi 

は、しかし、誰かがこのテストページを発見し、完全に良性のテストメッセージや小.jpgのように思える提出しました。これは私と他の約3人だけが知っている非直感的なURLを持つ非公開のテストページです。他のどの人もこのテストを送っていませんでした。

これは明らかに何かが起こっていることを心配しています。私は、このページが安全であることを確かめるために十分なセキュリティがわからないと心配しています。

紛失していることが明らかですか?

+0

($ _FILES ['upload'] ['name'] 'の中の)ユーザーが指定したファイル名は信頼できず、簡単に変更できます。これらの拡張子はチェックしないでください。 'getimagesize()'が有効な結果を返すかどうかを調べるには、mimeの型を調べます。可能であれば、独自のファイル名を生成します。 – MarcDefiant

答えて

8

アップロードを処理するときは、$ _FILES配列にあるすべてのデータを偽造することができることに注意してください。 HTTP経由で移動しているので、image/jpg mimeをexempleの実行可能ファイルに与えるのはかなり簡単です。

の1-真パントマイム

PHPをチェックし、ファイルの実際のMIMEをチェックするために、いくつかの機能が付属しています。

利用:そのためにあなたは明らかにのみ画像をアップロードしたいので、受信したファイルは、幅と高さを持っている必要があり、画像のプロパティ

をチェックfileinfo

$finfo = new finfo(FILEINFO_MIME, "/usr/share/misc/magic"); 
$filename = "/var/tmp/afile.jpg"; 
echo $finfo->file($filename); 

2-使用する必要がありますgetImageSize()を入力して、画像に関する必要な情報をすべて取得します。 falseを返すと、ファイルはおそらくイメージではなく、削除することができます。 getImageSizeはMIMEタイプも指定できますが、信頼できるかどうかはわかりません。

2.5-再処理画像

user628405によって示唆されるように、GDで画像を再処理することは、おそらく行うには、より安全なものです。

$img = imagecreatefrompng('vulnerable.png'); 
imagepng($img, 'safe.png'); 

もちろん、画像の種類に合わせて調整する必要があります。 phpのドキュメントでimagecreatefrom *をすべて参照してください。

、3-アップロードフォルダ あなたはすでにやっていることのほか:

をアップロードフォルダがウェブから利用できないことを確認してください。アップロードしたファイルを検証し、必要に応じて他のフォルダに移動して、ファイルの名前を変更します。 これは、ハッカーが悪意のあるファイルを実行するのを防ぎます(URLで到達できない場合は実行できません)。

さらに読書:https://www.owasp.org/index.php/Unrestricted_File_Upload

+2

バイナリデータに '<?php phpinfo();?>'が挿入されているWebサーバのPNGファイルにアップロードした人がいると、状況が発生しました。このコードは実行可能ではありませんが、 'include()'関数を介してアクセス可能です。そして残念ながら 'getimagesize()'は偽でない値を返しました。私は '$ img = imagecreatefrompng( 'vulnerable.png')によってすべてのアップロードされた画像を再保存してこの状況を管理しました。 – CodingHamster

+0

私はこれについてかなり新しく、自分の宿題を恐れていませんが、いくつかの質問があります:まず、fileinfoコマンドとgetImageSizeコマンドを追加しますか? 、ファイルの名前変更ビットと同様に、スクリプトの "case 'file'"部分の中に? – JeanSibelius

+0

すべてのチェックは '$ _FILES ['my_files'] ['tmp_name']'変数でできるだけ早く行う必要があります。万事がうまくいくなら、あなたはファイルを移動し、名前を変更して、それを使って何かする必要があれば何でもすることができます。 – grunk

0

ファイルのMIMEタイプを確認できますが、PHPハンドラが.phpファイルのみを実行でき、アップロードされた.phpファイルをスクリプトに保存しないようにしている限り、セキュリティ漏えいを起こすことはありません。

これは、もちろんサーバーにインストールされている他のサーバー側スクリプト言語と同様に、.phpファイルにも有効です。

あなたが受け入れている拡張機能の白をファイルシステムに保存することをお勧めします。

+1

これはfielのアップロードには直接関係しませんが、いくつかの悪意のあるPHPコードを含む画像をコメントとしてアップロードすることができます。サイトにLFIの脆弱性が存在する場合は、おそらく画像を含めて悪質なコードを実行する可能性があります。 – MarcDefiant

0

受信ファイルのMIMEタイプとファイル拡張子は無視します。これらは偽造することができます。

あなたがその道を下っている場合、それらのファイルをディレクトリに格納します。

このディレクトリは画像(音楽)用のものであることを確認してから、ファイル形式を確認してスクリプトに正しい拡張子を付けるようにしてください。

また、そのディレクトリでPHP(または何か他のもの)を実行できないようにしてください。

これは安全です。

4

コンテンツタイプを含むクライアントからの任意のデータに依存しないでください!

アップロードしたファイルをWebルートに保存しないでください。アップロードされたファイルは、より良い制御のために、スクリプトを介してのみアクセス可能でなければなりません。

アップロードしたファイルを元のファイル名と拡張子で保存しないでください!このデータを後で検索するためにデータベースに格納する。

関連する問題