ファイルシグネチャ検査
ファイルに含まれているデータを使用するためには、関連するソフトウェアが必要である。ソフトウェアの立場から眺めてみると、ソフトウェアが処理する過程または作業成果物を保存するためには、そのソフトウェアが後で読むことができるよう、独自のファイルフォーマットを作ったのだ。
画像ファイル(JPG、GIF、PNG、BMP、...)また、ファイルごとに固有のフォーマットを持っており、グラフィックスビューアプログラムを使用して、ファイルが表す画像を画面に出力することができるのは、グラフィックビューアプログラムがそれぞれのファイルごとに持っている固有のフォーマットを読み取ることができるよう実装がされているからである。
このように、ファイルごとに持っている固有のフォーマットを持っているが、このフォーマットを区分する基本的な情報がすぐにファイルシグネチャ(File Signature)である。JPGのファイルの場合、ファイルの内容を16進数で表現すると、ファイルは0xFF、0xD8に開始するが、このような情報がフォーマットを区別する基準となるものである。
ファイルシグネチャ検査とは、ファイルのフォーマットごとに定められたシグネチャの位置と値を比較して、対象のファイルが同じフォーマットであることを確認することをいう。
- 自動的にファイルシグネチャをチェックする
-
DEXTUpload.NET Professional製品は、HTTPモジュールで一時ファイルを作成する作業を行うと同時に、様々なフィルタリング処理も行われる。ファイルシグネチャ検査は、モジュールの一時ファイルの作成が完了した時点ですぐに実行される。
ファイルシグネチャ検査をするには、Webアプリケーションの「Web.config」ファイルを開いて「dextupload.net」セクション「settings」要素の「methodFileSignatureChecking」属性を設定する必要がある。
<dextupload.net> <!-- 「noChecking、absenceNotAllow、absenceOrSame」のいずれかを設定し、デフォルト値は「noChecking」だ。 --> <settings ... methodFileSignatureChecking="absenceOrSame" ... /> </dextupload.net>
- 「noChecking」:何の設定がされていないときと同じ値により、ファイルシグネチャ検査を実行していない。
- 「absenceNotAllow」:検査しようとするファイルのシグネチャ情報が存在しないか、検査結果が一致しない場合は、リンク先のファイルを制限する。
- 「absenceOrSame」:ファイルシグネチャ情報が存在する場合、検査結果が一致しない場合は、対象ファイルを制限する。
ファイルシグネチャ検査をするには、基準となるシグネチャ情報が必要である。この情報は、既にコンポーネント内部に含まれている。しかし、すべてのシグネチャ情報を一度に入れることができないため、欠落しているシグネチャ情報があるはずだ。もしシグネチャリソースにGIFファイル形式に関する情報がない場合、検査しようとする対象のファイルがGIFであれば、「methodFileSignatureChecking」属性の値を「absenceNotAllow」に設定しておけば、ターゲットは、制限がされてフィルタリングされる。一方で「absenceOrSame」は、リソースのGIFシグネチャ情報がないので、制限なしに渡される。
ファイル形式が制限されると、基本的に例外が発生するので、特別な例外処理をしていない以上、クライアントにHTTP 500ステータスコードが返される。ファイルシグネチャ検査によってファイルがフィルタリングされたとしても、「filterAction」属性の値が「flushing」であれば、エラーではなく、0バイトのファイルに変更されることができ、「compact」属性の値が「true」の場合、エラーなしに、これらのファイルのフォームフィールドが削除された状態でページやハンドラに渡される。
テキスト形式(txt)のファイルは、リソースのシグネチャ情報がないため、「absenceNotAllow」に設定すると、常にエラーが発生する。したがって、ファイルシグネチャ検査でtxt、xmlのようなファイルを許可するには、「absenceOrSame」に設定ヘジュオヤする。
- 内蔵されたリソースではなく、外部リソースを参照して、ファイルシグネチャ検査する
-
コンポーネントに組み込まれたシグネチャリソースは、更新速度が遅くなることがあります。新しいシグネチャ情報が追加されたか、問題のあるシグネチャが変更された場合、公式バージョンの更新を待たずに変更されたリソースファイルで先に受け取ることができる。
内蔵されたリソースではなく、変更されたリソースファイルを参照する方法は、「Web.config」ファイルを開いて「dextupload.net」セクション「settings」要素の「signatureDataFilePath」属性にファイルのパスを指定すればよい。
<dextupload.net> <!-- 〜/で始まる場合は、Webアプリケーションのルートを基準とする相対パスを示し、必要に応じて、c:\ tempのように絶対パスを使用することができる。 --> <settings ... methodFileSignatureChecking="absenceOrSame" signatureDataFilePath="~/files/dextupload-1.1.2.0.dxfs" ... /> </dextupload.net>
- 手動で検査をしようとする場合、
-
ファイルシグネチャ検査をHTTPモジュールで行わず、ページやハンドラまたはコントローラ(MVC環境であれば、)から直接検査をしようとするなら「FileSignatureAnalyzer」クラスを使用する。
<dextupload.net> <!-- noCheckingに設定するか、methodFileSignatureChecking属性を削除する。 --> <settings ... methodFileSignatureChecking="noChecking" ... /> </dextupload.net>
ファイルシグネチャ検査を手動でするには、「FileElement.Save、FileElement.SaveAs、FileUpload.SaveAll」メソッドなどを実行する前に、「FileSignatureAnalyzer「クラスの「Check」メソッドを使用して、一時ファイルのシグネチャ情報を確認することができる。
using (var dext = new FileUpload()) { //シグネチャ検査ツールを生成する。 var fsa = new FileSignatureAnalyzer(); //チェックするファイルが1つしかあるとすれば var element = dext.GetSingleFileElement(); if (!element.IsEmpty) { //ファイルの拡張子名シグネチャの内容が一致しているかどうかのチェックを実行する。 var fsr = fsa.Check(element.FileExtension, element.TempFilePath); switch (fsr) { case FileSignatureResult.Absence: //この拡張子のシグネチャ情報がリソースに存在しない場合である。 ... break; case FileSignatureResult.Different: //ファイルがシグネチャ情報と一致しない場合である。 ... break; case FileSignatureResult.Same: //ファイルがシグネチャ情報と一致する場合である。 break; } } }
ASP.NET MVCであれば、
[HttpPost] public ActionResult Upload([Bind(Prefix = "file1")] DEXTPostedFile file) { if (file != null) { //シグネチャ検査ツールを生成する。 var fsa = new FileSignatureAnalyzer(); //ファイルの拡張子名シグネチャの内容が一致しているかどうかのチェックを実行する。 var fsr = fsa.Check(file.Element.FileExtension, file.Element.TempFilePath); switch (fsr) { case FileSignatureResult.Absence: //この拡張子のシグネチャ情報がリソースに存在しない場合である。 ... break; case FileSignatureResult.Different: //ファイルがシグネチャ情報と一致しない場合である。 ... break; case FileSignatureResult.Same: //ファイルがシグネチャ情報と一致する場合である。 break; } } }
「FileSignatureAnalyzer」は、内部リソースを使用してファイルシグネチャ検査を実行する。もし外部リソースを使用して検査をしたい場合は、コンストラクタにファイルのパスを指定すればよい。
//外部リソースを使用してシグネチャ検査ツールを生成する。 //外部リソースファイルのパスは、必ずドライブ文字列で始まるか、UNCパスでなければならない。 var fsa = new FileSignatureAnalyzer(@"c:\temp\dextupload-1.1.2.0.dxfs");
- ファイルシグネチャ検査の留意事項
-
- テキスト形式のファイルは、シグネチャのリソースを作成するときに、除外される。
- ファイルシグネチャ検査は、ファイルを開いて内容を確認するため、短い時間ですが、ファイルI / O操作を実行するため、全体的なファイルのアップロード速度が遅延することができる。
- 「FileSignatureAnalyzer」を作成すると、外部リソースファイルを使用すると、「FileSignatureAnalyzer」オブジェクトを作成するたびに、リソースファイルを読み取るファイルI / O操作があるので、パフォーマンスに影響を与えることができる。
- ファイルシグネチャリソースは完璧ではないので、製品と一緒に定期的に更新される。
- ファイルシグネチャ検査は、ファイルフォーマットを区分するいくつかのデータを比較する作業であるため、ファイルのヘッダとフッタを完全に分析するものではない。したがって、全く別のフォーマットに偽装したマルウェア(JPGを偽装したシェルスクリプトのように)ではなく、フォーマットの脆弱性を利用した悪性コードのような場合には、検査がほとんど不可能である。
- 拡張子名は異なりますが、シグネチャは、同じフォーマットが非常に多いので、明確にフォーマットを区分する目的で使用することも不可能である。ファイルシグネチャ検査は、完全なフォーマットのチェックがではなく、拡張子の名前をチェックすることも、より高いレベルの検査日だけなので、攻撃者による変形攻撃を完全に防ぐことができないことに注意する。