Strict-Transport-Security Multiple Header Entries (Non-compliant with Spec)

概要

  • 脆弱性の名前: Strict-Transport-Security Multiple Header Entries (Non-compliant with Spec) (HSTSヘッダーの複数設定による仕様違反)
  • 問題の要点: WebサイトがStrict-Transport-Security (HSTS) ヘッダーを複数回設定しているため、ブラウザがどのようにHSTSを処理すべきか不明確になり、セキュリティ上のリスクが生じる状態。
  • よくある発生シーン: サーバー設定、アプリケーション設定、CDN設定など、複数の箇所でHSTSヘッダーを設定してしまい、設定が重複している場合に発生しやすい。クラウド環境では、複数のサービスを連携させる際に設定の管理が煩雑になり、設定ミスが起こりやすい。

背景

HSTS (HTTP Strict Transport Security) は、WebサイトへのアクセスをHTTPS経由のみに限定するようブラウザに指示するセキュリティ対策です。HSTSヘッダーは、ブラウザに対してWebサイトがHTTPSでのみアクセスされるべきであることを通知し、中間者攻撃(Man-in-the-Middle Attack)のリスクを軽減します。
HSTSヘッダーはRFC 6797で定義されており、仕様ではHSTSヘッダーは一度だけ設定されるべきとされています。複数のHSTSヘッダーが設定されている場合、ブラウザの挙動は定義されておらず、セキュリティ上の問題を引き起こす可能性があります。

セキュリティ上のリスク

  • HSTSが正しく適用されない可能性。
  • 中間者攻撃による通信の盗聴や改ざん。
  • HTTP経由でのCookie窃取。
  • セッションハイジャックのリスク。
  • SSL Stripping攻撃に対する脆弱性。

対処方法の具体例

Apache2

httpd.confでの設定

httpd.conf または vhost.conf でHSTSヘッダーが重複して設定されていないか確認し、一箇所でのみ設定するように修正します。

# httpd.conf または vhost.conf
<VirtualHost *:443>
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</VirtualHost>

Nginx

nginx.confでの設定

nginx.conf でHSTSヘッダーが重複して設定されていないか確認し、一箇所でのみ設定するように修正します。

# nginx.conf
server {
    listen 443 ssl;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
    ...
}

WordPress

.htaccessでの設定

.htaccess でHSTSヘッダーが重複して設定されていないか確認し、一箇所でのみ設定するように修正します。

<IfModule mod_headers.c>
    Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</IfModule>

functions.phpでの設定

functions.php でHSTSヘッダーが設定されている場合、.htaccess との設定が重複していないか確認し、どちらか一方に設定を統一します。

<?php
// functions.php
add_action('send_headers', function() {
    header('Strict-Transport-Security: max-age=31536000; includeSubDomains; preload');
});

PHP

PHPコードでの設定

PHPコード内で header() 関数を使用しHSTSヘッダーを設定している場合、サーバー設定や他の場所での設定と重複していないか確認し、一箇所でのみ設定するように修正します。

<?php
// PHPコード
header('Strict-Transport-Security: max-age=31536000; includeSubDomains; preload');

JavaScript (Node.js / Express)

Express.jsでの設定

Express.js で helmet ミドルウェアを使用している場合、他の場所でのHSTSヘッダー設定と重複していないか確認し、一箇所でのみ設定するように修正します。

const express = require('express');
const helmet = require('helmet');
const app = express();

app.use(helmet.hsts({
  maxAge: 31536000,
  includeSubDomains: true,
  preload: true
}));

AWS

CloudFrontの設定

CloudFrontを使用している場合、カスタムヘッダーポリシーでHSTSヘッダーが重複して設定されていないか確認し、一箇所でのみ設定するように修正します。

Load Balancerの設定

ロードバランサー(ALB/ELB)を使用している場合、HTTPヘッダーの書き換えルールでHSTSヘッダーが重複して設定されていないか確認し、一箇所でのみ設定するように修正します。

検出方法

OWASP ZAP での出力例

  • Alert 名: Strict-Transport-Security Multiple Header Entries (Non-compliant with Spec)
  • リスク: Low
  • URL: HSTSヘッダーが複数設定されているURL
  • パラメータ: なし
  • 詳細: レスポンスヘッダーに Strict-Transport-Security が複数含まれているという情報

手動再現例

  1. Webブラウザの開発者ツールを開き、Networkタブを選択します。
  2. HTTPSで提供されているページにアクセスし、HTTPレスポンスヘッダーに Strict-Transport-Security ヘッダーが複数含まれていないか確認します。
  3. curl コマンドを使用して、HTTPレスポンスヘッダーを確認します。
curl -I https://example.com

まとめ

  • CVSS 基本値: 4.0 (Medium)
  • 運用チームや開発者が意識すべきポイント:
    • HSTSヘッダーの設定箇所を特定し、重複設定を避ける。
    • Webサイト全体でHTTPSを適用する。
    • HSTSヘッダーを設定し、HTTPアクセスをHTTPSにリダイレクトする。
    • HSTSの設定をサブドメインにも適用する。
    • HSTS preload listへの登録を検討する。
    • 定期的にWebサイトのセキュリティ診断を実施する。
  • 再発防止:
    • 開発プロセス全体でセキュリティを考慮する (Security by Design)。
    • コードレビューを実施し、HSTSヘッダーの設定が重複していないか確認する。
    • 自動脆弱性診断ツールを導入し、定期的にスキャンを行う。
    • HTTPS化に関するポリシーを策定し、遵守する。
    • 設定管理ツール(IaC)を導入し、設定の一貫性を保つ。

補足資料・参考 URL

以上の対策と検出方法を活用して、Strict-Transport-Security Multiple Header Entries (Non-compliant with Spec) のリスクを低減してください。