任意ユーザが投稿したzipファイルを安全にダウンロードするには？


任意ユーザが投稿した(任意のプログラム系の)zipファイルを、PHPで安全にダウンロードする仕組みを作りたいのですが、注意すべきことは何ですか？  
HTML出力の場合は「特殊文字を HTML エンティティに変換」しますが、ダウンロードの場合に該当する処理はありますか？  
例えば、zipファイル形式ではなく、個別ファイルでexe形式以外の拡張子のみokとすれば安全ですか？




サーバーにアンチウイルスソフトをインストールしてアップロードしたコンテンツに対して実行する方法があります。  
定義ファイルも更新が必要になりますし、面倒なので、どうしても必要性がない限りはこういう機能は作らない方がいいです。

Linux用のオープンソースのアンチウイルスソフト  
<http://www.clamav.net/>

単純にダウンロードの実装をしたいなら、以下のようにヘッダーを指定してください。

[code]

    $filename = 'download.zip';
    $filepath = '/home/user/file.zip';
    header('Content-Type: application/force-download');
    header('Content-Length: '.filesize($filepath));
    header('Content-Disposition: attachment; filename="'.$filename.'"');
    readfile($filepath);
    
[/code]




ユーザーがファイルをアップロード可能な場合、サービスに応じた特定の形式のコンテンツのみを受け入れるようにすべきです。任意のファイルまたはアーカイブをアップロード/ダウンロード可能にすべきではありません。任意のファイルをアップロード/ダウンロード可能なサービスは、リスクを度外視するか、利用者がリスクを認識したうえでしか成立しません。

アンチウイルスソフトは気休め程度の対策にしかなりません。世間に出回っているマルウェア(と似ているもの)は排除できますが、例えば私がいま「特定のファイル(群)を消去する実行ファイル(を含んだzip)」を作ったとして、それはアンチウイルスソフトではたいてい検出できません。

エスケープというのは、「ある文脈において、その文脈を破壊するようなデータを文脈に適した形に変換する」ものです。危険なものを安全にするとか、危険なものを排除する仕組みではありません。HTMLであれば、エンドユーザー入力をもとの文脈を破壊しないようにエスケープすれば元の文脈以上に危険なことにはなりません。ところが任意のバイナリには「元の文脈」が存在しないので、エスケープのしようがありません。

