Strict-Transport-Security Header Not Set

概要

  • 脆弱性の名前: Strict-Transport-Security Header Not Set (HSTSヘッダー未設定)
  • 問題の要点: WebサイトがHTTPSで提供されているにもかかわらず、Strict-Transport-Security (HSTS) ヘッダーが設定されていないため、ユーザーがHTTP経由でアクセスするリスクが残る状態。
  • よくある発生シーン: HTTPSへの移行後、HSTSヘッダーの設定を忘れている場合や、CDNやロードバランサーの設定が不適切な場合に発生しやすい。クラウド環境では、複数のサービスを組み合わせる際に設定の不整合が起こりやすい。

背景

HSTS (HTTP Strict Transport Security) は、WebサイトへのアクセスをHTTPS経由のみに限定するようブラウザに指示するセキュリティ対策です。HSTSヘッダーが設定されていると、ブラウザはHTTPでのアクセスを自動的にHTTPSにリダイレクトします。これにより、中間者攻撃(Man-in-the-Middle Attack)のリスクを軽減できます。
HSTSヘッダーが設定されていない場合、ユーザーがHTTPでアクセスする可能性が残り、通信が暗号化されずに盗聴や改ざんのリスクが生じます。
WebサイトのHTTPS化が進むにつれて、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>
  • max-age: HSTSを有効にする期間を秒単位で指定します(例:31536000秒 = 1年間)。
  • includeSubDomains: サブドメインにもHSTSを適用します。
  • preload: HSTS preload listへの登録をリクエストします(任意)。

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ヘッダーを設定します。

<?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 Header Not Set
  • リスク: 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)
  • 運用チームや開発者が意識すべきポイント:
    • Webサイト全体でHTTPSを適用する。
    • HSTSヘッダーを設定し、HTTPアクセスをHTTPSにリダイレクトする。
    • HSTSの設定をサブドメインにも適用する。
    • HSTS preload listへの登録を検討する。
    • 定期的にWebサイトのセキュリティ診断を実施する。
  • 再発防止:
    • 開発プロセス全体でセキュリティを考慮する (Security by Design)。
    • コードレビューを実施し、HSTSヘッダーの設定を確認する。
    • 自動脆弱性診断ツールを導入し、定期的にスキャンを行う。
    • HTTPS化に関するポリシーを策定し、遵守する。

補足資料・参考 URL

以上の対策と検出方法を活用して、Strict-Transport-Security Header Not Set のリスクを低減してください。