すべての解説
深刻度:中セキュリティヘッダー

MIMEスニッフィングとX-Content-Type-Options:nosniffの解説

ブラウザはサーバーが誤ったContent-Typeを送信しても、レスポンスの実際のコンテンツを「スニッフィング」して処理方法を決定できます。X-Content-Type-Options: nosniffヘッダーは、宣言されたタイプを信頼し、アップロードされた画像などのファイルを実行可能なスクリプトに昇格させることを拒否するようブラウザに指示します。

これは何か

MIMEスニッフィングは、サーバーのContent-Typeヘッダーがないかコンテンツとマッチしないとき、レスポンスの最初のバイトを検査してコンテンツタイプを推測するブラウザのヒューリスティックです。例えば、<script>で始まるtext/plainとして宣言されたファイルは、HTMLとして再分類・実行される可能性があります。

X-Content-Type-Optionsは単一値のレスポンスヘッダーです:X-Content-Type-Options: nosniff。存在する場合、ブラウザはレスポンスを別のMIMEタイプに昇格させることを拒否します。application/octet-streamとして配信されるアップロードファイルはバイナリのままで、実行可能なスクリプトやスタイルシートにはなりません。

なぜ重要か

ユーザー生成コンテンツが主なリスクです。アプリでファイルのアップロードが許可されており、それをアプリと同じオリジンから配信している場合、画像に偽装した悪意あるHTMLファイルがスニッフィングされると被害者のブラウザで実行される可能性があります。サーバー側で拡張子を検証していても、ファイルアップロードを通じた保存型XSSが成立します。

nosniffがなければ、ブラウザは予期しないソースから取得したスタイルシートも実行する場合があります。スクリプトとして実行されるスタイルシートは、他の設定ミスと組み合わさるとクロスオリジンデータ流出の経路を生み出します。nosniffはアプリのすべてのコンテンツ境界を強化する低コストのグローバルな保護手段です。

直し方

Next.jsでグローバルにヘッダーを追加する

next.config.jsでX-Content-Type-Options: nosniffを設定して、APIルートや静的ファイルルートを含む全レスポンスに適用されるようにします。

// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: "/:path*",
        headers: [
          { key: "X-Content-Type-Options", value: "nosniff" },
        ],
      },
    ];
  },
};
nginxで設定する

serverブロックにディレクティブを追加して、nginxを通じて送信されるすべてのレスポンスに適用されるようにします。

add_header X-Content-Type-Options "nosniff" always;
常に正確なContent-Typeを宣言する

nosniffは各レスポンスが正しいContent-Typeヘッダーも持つ場合に最も効果的です。ユーザーアップロードファイルには適切なタイプを付け、アプリと同じオリジンではなく別のオリジンやストレージドメインから配信することで、ファイルが実行されてもセッションCookieにアクセスできないようにします。

拡張子だけでなくコンテンツでアップロードを検証する

拡張子チェックは回避できます。file-type(npm)などのライブラリを使ってサーバー側でファイルのマジックバイトを検査し、許可された安全なタイプのリストに一致しないものはストレージ層に到達する前に拒否します。

import { fileTypeFromBuffer } from "file-type";

const ALLOWED = new Set(["image/jpeg", "image/png", "image/webp", "image/gif"]);

async function validateUpload(buffer: Buffer): Promise<void> {
  const type = await fileTypeFromBuffer(buffer);
  if (!type || !ALLOWED.has(type.mime)) {
    throw new Error("Upload rejected: unsupported file type");
  }
}

FAQ

AppSafeはX-Content-Type-Optionsヘッダーの欠如をどの深刻度で報告しますか?

中。このヘッダーは低コストのハードニング手段(1行の設定)なので、省略は明確なギャップですが、積極的な悪用には別のアップロードまたはインジェクションの経路が必要です。

nosniffは通常のページ読み込みに影響しますか?

実際にはありません。nosniffはより危険なタイプへの昇格のみをブロックします。HTML、CSS、JavaScriptはすでに正しいタイプで配信されているため、通常通り読み込まれます。

モダンブラウザがより賢くなった今もX-Content-Type-Optionsは必要ですか?

はい。スニッフィングの動作はエンジンとバージョン間で異なり、このヘッダーは唯一のポータブルな保証手段です。現行のすべてのブラウザ(Chrome、Firefox、Safari、Edge)はnosniffを尊重します。

あなたのアプリは大丈夫ですか?

AppSafeなら、この問題を含む数十項目を1回の無料スキャンでチェックできます。

アプリを無料でスキャン