ファイルのアップロードのセキュリティ開発ガイド
ファイルのアップロード機能を提供するサービスは、外部からのセキュリティに影響を与えることができる攻撃を受けることができる。たとえば、攻撃者が悪質なファイルをアップロードして、サーバーに保存されたウェプスェル(Web-Shell)を実行することができる。ほとんどのサービスは、ファイル添付機能を含んでいるが、アップロードするファイルの妥当性を検証するセキュリティコードが存在しない場合、これを悪用して、サーバーの権限を取得したり、サービスに有害を加える行為をしようとすることができる。
ASP、ASP.NET、PHP、JSP、(Servlet)など、すべてのプラットフォームでは、基本的にアップロードされたファイルに対して検証次元の防御をしていない。したがって、サービスを提供する開発者は、クライアント(ブラウザ、third-party)から送信されたファイルのデータを検証する作業コードを作成しなければならない。
- クライアント領域でファイルの拡張子のフィルタリング
-
ファイルのアップロードをするときは、許可されたファイルのみにフィルタリングをしなければならない。
ファイルの添付先は、サービスの性質に依存してなるが、一般的な場合には、一般的に使用されるメディアファイルを除いては、アップロードを許可してはならない。(doc、docx、xls、xlsx、hwp、...、jpg、png等許可)したがって、メディアファイルを除くjsp、asp、php、cgiのファイルがアップロード禁止対象となる。
純粋なHTMLを使用した場合、JavaScriptコードを使用して、ファイルの拡張子名を確認することができ、ActiveXのようなPlug-inの技術を使用したコンポーネントを使用する場合には、コンポーネント自体の拡張子のフィルタリング機能を使用するようにする。
ファイルの拡張子を検証するためのコードは、アップロードが禁止されたファイルの拡張子をチェックする方法(Black List)よりアップロードが可能なファイル拡張子かどうかチェックする方法(White List)を使用する。
クライアント側で適切な検証を経たとしても、サーバーに送信される過程で、データ変調が起こる場合がある。HTTPプロトコルでは、これを守る方法はないので、SSL(Secure Socket Layer)を使用して暗号化送信をしなければならない。
SSLは、トランスポート層(Transport Layer)ただし、暗号化を実行するため、開発者の立場では、別に処理する部分はない。ただし、SSLは、要求データを暗号化/復号化する過程があるので、全体的なパフォーマンス(体感応答速度)が低下することができる。
- サービス(サーバー)領域でファイルの拡張子のフィルタリング
-
クライアント側での検証が行われたとしても、簡単にバイパスが可能なため、サーバー側のコードでも、同じ検査を実行しなければならない。
クライアント検査方法と同様にWhite Listに基づいて拡張子のチェックを実行する必要があり、クライアント側から渡されたファイル名を前処理せずにそのまま検査することが、セキュリティ上のはるかよい。
例えば、trim(スペースで処理される文字セットを削除)処理をしたり、特殊文字を削除するなどの作業をしないで、元のファイル名のまま検査を行う必要があり、そもそもWhite Listに含まれていない拡張子を持つファイルである場合は、サーバーに保存しないようにしなければならない。Black Listの方法で拡張子フィルタリングをする場合には、攻撃者が繰り返し作業を通じてBlack Listに含まれていないパターンを見つけて攻撃することができますので、必ずWhite List検証方式を使用するようにする。
- アップロードディレクトリの実行権限の削除
-
特殊目的がない限り、一般的にアップロードされたファイルは、ダウンロードをするための対象となる。
ウェプスェルファイルが保存されたとしても、このファイルが実行されない場合は、セキュリティに深刻な影響を与えない。したがって、ファイルを保存するディレクトリは、必ず実行権限を削除する必要がある。
例)IISのセキュリティ設定
IISの設定で、ターゲットディレクトリを選択した後、プロパティウィンドウを開いて、実行権限を「なし」に設定する。
例)IIS7以上の場合
IIS7以上の場合には、アップロードディレクトリを選択した後、ハンドラマッピングツールを開いて、権限を変更する必要がある。
アクセス許可を編集項目でのスクリプトは、実行項目をチェック解除する。
例)Apacheの場合
Apacheの場合には、アクセス許可を削除する方法というよりは、アップロードディレクトリに保存できるファイルの対象を制限する方法を使用することができる。
#httpd.conf設定ファイル <Directory アップロードディレクトリのパス> AllowOverride FileInfo (あるいはAllも可能) </Directory>
アップロードディレクトリの下位に.htaccessファイルを作成して、特定のMIME-TYPEをファイルを変更してウェプスェルファイルが実行されないようにしなければならない。
<FilesMatch "\.(php|pl|cgi|inc|lib)"> Order allow, deny Deny from all </FilesMatch> AddType text/html .html .htm .php .php3 .php4. phtml .phps .in .cgi .pi .shtml .jsp
その他詳細については、Apache .htaccessファイルの設定を参照している。
http://httpd.apache.org/docs/2.4/mod/core.html#allowoverride
http://httpd.apache.org/docs/2.4/howto/htaccess.html
その他のWebサーバーやWASサーバーの設定は、関連文書を参照している。
- アップロードディレクトリのパス外部露出を削除
-
開発便宜のために、一般的にファイルのアップロードディレクトリの場所を、Webアドレスに露出させる場合が多い。ファイルをアップロードするプロセスは、気をつけて開発が、ダウンロードの部分は、追加の処理なしに、Webサーバーに一任する場合が多いので、アップロードされたウェプスェルを実行するためのターゲットになる。したがって、ファイルのアップロードディレクトリのパスは、サービスのサブディレクトリのパスに設定することを一次的に避けなければならず、外部ディレクトリを使用しても、Webアドレスへのアクセスを防ぐために、Web仮想ディレクトリに登録しないようにする。代わりにダウンロードをするためにダウンロードモジュールを開発し、そのモジュールで、外部ディレクトリからファイルを読み取る転送する機能を開発しなければならない。
- ファイル管理ポリシーの変更
-
ローカルドライブに保存されたファイル名のままサーバーに保存する場合が多い。業務上の管理の利便性のためにファイル名のまま保存をするようにポリシーを決定する場合が多いが、このような場合、重複ファイル名を避けるために追加のコードを作成するための努力が必要になるだけでではなく、ファイル名変動がないので、攻撃者がウェプスェル攻撃をするための有利な条件になるからである。
アップロード対象となるファイルは、ファイル固有のファイル名を使用せずにサービスポリシーに合わせて特殊なファイル名で作成して保存をするようにする。
例)
F [ファイルのアップロード時刻yyyyMMddHHmmssfff] _ [リモートアイピー] _ [セッションと一意のID] _ [スレッド] _ [順番]。[無意味な拡張子]
サイトを攻撃しよう.jsp - > F20130401153027125_111.111.111.111_0012345_100_0001.bin
そして、実際のローカルファイル名はダウンロードサービスのためにデータベースに登録して、必要なときに使用する。この時、ファイルのサイズ、拡張子、MIME-TYPE(可能な場合)などを一緒に登録すると、追加のセキュリティとサービスの実装に役立つ。加えて、ファイルのダウンロードは、必ずダウンロードモジュールを利用して提供をすれば、ユーザーの立場からも、データベースに登録されたユーザーフレンドリーなファイル名でダウンロードを受けることができるようになる。結論として、攻撃者はウェプスェルを実行するファイル名を知ることができないため、攻撃を試みることができない。ファイル名を知っている場合でも、ダウンロードモジュールを介してファイルにアクセスすることしかないので、サーバーは、そのファイルを実行していないクライアントに無条件ダウンロードがされる。そのためウェプスェル攻撃を容易に防ぐことができる。
- DEXTUpload.NET Professional
-
DEXTUpload.NET Professionalは、ファイルのアップロード攻撃を防ぐ独自のセキュリティ機能を持っていない。
DEXTUpload.NET Professionalは、アップロードがされたファイルを保存するときに、元のファイル名をそのまま保存したり、ファイル名に順番を付けたり、名前を付けて保存が可能である。しかし、製品に関係なく、プラットフォームの性質に応じて、ファイル名に特殊文字と非許可の文字が含まれて(攻撃者に意図された)された場合には、意図していないファイル名で保存することができたり、あるいはエラーが発生することがあります。したがって、ファイルを保存する前に、必ずファイル名が有効であるかの検査をしなければならない。