.txtまたは.csvファイルをアップロードできるようにしたいだけです。
簡単そうですね。そうではありません。そしてその後、いくつかの。
簡単な方法は、ファイルをファイルシステムに保存する前に、ファイルが「.txt」または「.csv」で終わることをテストすることです。これは、ファイルシステムの近くにユーザーが送信したファイル名を許可する前に、ファイル名に何を含めることができるかについてのより詳細な検証の一部である必要があります。
一部のプラットフォーム(特にWindows)では、ファイル名に何を含めることができるかに関する規則が複雑であるため、通常は、既知の適切な名前と拡張子を使用して独自のファイル名を個別に作成するのが最適です。
いずれの場合も、ブラウザが使用可能な名前のファイルを送信するという保証はありません。また、送信したとしても、名前の最後に「.txt」または「.csv」が付いているという保証はありません。テキストまたはCSVファイルです。(一部のプラットフォームは、ファイルの入力に拡張子を使用しません。)
ファイルの内容をスニッフィングしてファイルの種類を確認することはできますが、これは非常に信頼性が低くなります。例えば:
<html>,<body>,</body>,</html>
プレーンテキスト、CSV、HTML、XML、またはその他のさまざまな形式にすることができます。ユーザーがアップロードするファイルの種類を明示的に制御できるようにすることをお勧めします(または、種類ごとに1つのファイルアップロードフィールドを使用します)。
今ここでそれは本当に厄介になります。アップロードを受け入れて/data/mygoodfilename.txtとして保存し、Webサーバーがコンテンツタイプ「text/plain」として正しく提供しているとします。ブラウザはそれを何と解釈すると思いますか?プレーンテキスト?あなたはとても幸運なはずです。
問題は、ブラウザ(主にIE)がContent-Typeヘッダーを信頼せず、代わりにファイルの内容をスニッフィングして、他のファイルのように見えるかどうかを確認することです。上記のスニペットをプレーンテキストとして提供すると、IEはそれをHTMLとして喜んで扱います。HTMLには、ユーザーのサイトへのアクセスを引き継ぐクライアント側のスクリプトが含まれている可能性があるため、これは大きな問題になる可能性があります(クロスサイトスクリプティング攻撃)。
この時点で、たとえば「file」コマンドを使用して、サーバー側でファイルをスニッフィングして、「&lt;html>」が含まれていないことを確認したくなる場合があります。しかし、これは失敗する運命にあります。'file'コマンドは、IEと同じHTMLタグすべてをスニッフィングするわけではなく、他のブラウザはとにかく異なる方法でスニッフィングします。'file'がHTMLではないと主張するファイルを準備するのは非常に簡単ですが、それでもIEはそれがHTMLであるかのように扱います(セキュリティ災害の影響があります)。
'file'などのコンテンツスニッフィングアプローチでは、誤った安心感しか得られません。これは、ファイルタイプを大まかに推測するための便利なツールであり、効果的なセキュリティ対策ではありません。
この時点で、あなたの最後の絶望的な可能性は次のようなものです。
スクリプトインジェクション攻撃がメインサイトの資格情報を盗むことができないように、ユーザーがアップロードしたすべてのファイルを別のホスト名から提供します。
ユーザーがアップロードしたすべてのファイルをCGIラッパーを介して提供し、ヘッダー「Content-Disposition:attachment」を追加して、ブラウザーがそれらを直接表示しようとしないようにします。
信頼できるユーザーからのアップロードのみを受け入れます。