HSTS(HTTP Strict Transport Security)- HTTPSを強制する最後の砦

これは何?

HSTS(HTTP Strict Transport Security)は、ブラウザに「このサイトは必ずHTTPSでアクセスせよ」と指示するセキュリティヘッダーです。一度HSTSヘッダーを受信したブラウザは、指定期間中、そのドメインへのすべてのアクセスを自動的にHTTPSに変換します。

HSTSヘッダーは、以下の形式でHTTPSレスポンスに含めます:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

この設定は「今後1年間(31536000秒)、このドメインとすべてのサブドメインは必ずHTTPSでアクセスせよ。HSTSプリロードリストに登録することを許可する」という意味です。

なぜ重要なのか

HTTPSを導入しても、以下のような脆弱性が残ります:

1. 最初のアクセスはHTTPの可能性

ユーザーがアドレスバーにexample.comと入力すると、ブラウザはまずhttp://example.comにアクセスします。サーバーがhttps://example.comにリダイレクトしますが、この最初のHTTPリクエストは平文で送信され、盗聴や改ざんのリスクがあります。

2. SSLストリッピング攻撃

攻撃者が中間者となり、HTTPSをHTTPに降格させる攻撃です:

  1. ユーザーがhttp://bank.comにアクセス
  2. 攻撃者がHTTPSリダイレクトを遮断し、HTTPのまま返す
  3. ユーザーはHTTPでログイン情報を送信し、攻撃者に盗まれる

HSTSがあれば、ブラウザは過去の記録から「このサイトはHTTPSのみ」と知っているため、HTTPリクエストを送信せず、最初からHTTPSでアクセスします。

3. ユーザーのミスタイプ

ユーザーがhttp://bank.comとブックマークしていたり、古いリンクをクリックした場合、HTTPでアクセスされる可能性があります。HSTSがあれば、ブラウザが自動的にHTTPSに変換します。

攻撃の仕組み

SSLストリッピング攻撃の詳細

2009年に発表されたこの攻撃は、HTTPSの普及期に大きな脅威でした:

  1. 準備: 攻撃者が公衆Wi-Fiなどで中間者攻撃の体制を整える(ARPスプーフィングなど)
  2. 最初のHTTPリクエスト: ユーザーがhttp://example.comにアクセス
  3. リダイレクトの遮断: サーバーはhttps://example.comにリダイレクトしようとするが、攻撃者が介入
  4. HTTPのまま維持: 攻撃者がユーザーにはHTTPのまま応答し、サーバーにはHTTPSで中継
  5. 盗聴・改ざん: ユーザーとサーバー間の通信を、攻撃者が平文で読み書きできる

HSTSがある場合、ブラウザは過去の訪問記録から「このサイトはHTTPSのみ」と知っているため、ステップ2でHTTPリクエストを送らず、最初からHTTPSでアクセスします。

Cookie盗聴攻撃

HSTSにはincludeSubDomainsオプションがあり、これがないとサブドメインが狙われます:

  1. メインドメインexample.comはHTTPS + HSTS
  2. サブドメインblog.example.comはHTTPSだがHSTSなし
  3. 攻撃者がhttp://blog.example.comへのアクセスを中間者攻撃
  4. メインドメインのCookieがサブドメインに送信され、盗聴される

includeSubDomainsを設定すれば、すべてのサブドメインもHSTSで保護されます。

実際の被害事例

Moxie Marlinspike氏のsslstrip(2009年)

セキュリティ研究者のMoxie Marlinspike氏が、SSLストリッピング攻撃を実装した「sslstrip」ツールを公開しました。このツールは、公衆Wi-Fiで簡単にHTTPS通信を盗聴できることを実証し、HSTS開発の契機となりました。

中国のGreat Cannon攻撃(2015年)

中国政府の検閲システムが、Baiduの広告スクリプトを改ざんし、GitHubへのDDoS攻撃を実行しました。Baiduのスクリプトが一部HTTPで配信されていたため、中間で改ざん可能でした。HSTSがあれば、このような攻撃を防げた可能性があります。

Wi-Fiパイナップル攻撃

ハッカーが「Wi-Fi Pineapple」という装置を使い、公衆Wi-Fiを模倣して中間者攻撃を行う事例が多発しています。HTTPSサイトでも、HSTSがなければSSLストリッピングで攻撃されます。2018年の調査では、主要空港やカフェのWi-Fiで、こうした攻撃が実際に観測されています。

Nyambushでの検出内容

Nyambushは、以下の項目をチェックします:

  1. HSTSヘッダーの存在: HTTPSレスポンスにStrict-Transport-Securityヘッダーがあるか
  2. max-ageの長さ: 推奨は1年以上(31536000秒)
  3. includeSubDomainsの有無: サブドメインも保護されているか
  4. preloadの有無: HSTSプリロードリストへの登録準備ができているか
  5. HTTPでのアクセス: HTTPからHTTPSへ正しくリダイレクトされるか

スキャン結果では、HSTSが未設定の場合、Webサーバーの設定例を提示します。

対策方法

1. HSTSヘッダーの追加

Nginxの場合

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    # SSL証明書の設定(省略)

    # HSTSヘッダー(1年間、サブドメイン含む、preload対応)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    location / {
        root /var/www/html;
        index index.html;
    }
}

重要: alwaysを付けないと、エラーレスポンス(404、500など)でヘッダーが送信されません。

Apacheの場合

<VirtualHost *:443>
    ServerName example.com

    SSLEngine on
    # SSL証明書の設定(省略)

    # HSTSヘッダー
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

    DocumentRoot /var/www/html
</VirtualHost>

mod_headersモジュールが必要です:

sudo a2enmod headers
sudo systemctl restart apache2

Node.js/Expressの場合

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

const app = express();

// helmetでHSTSを有効化
app.use(helmet.hsts({
  maxAge: 31536000, // 1年
  includeSubDomains: true,
  preload: true
}));

app.get('/', (req, res) => {
  res.send('Hello, secure world!');
});

app.listen(443);

2. 段階的な導入

いきなり1年間(max-age=31536000)に設定すると、問題が起きた時に後戻りできません。段階的に導入します:

ステップ1: 短期間でテスト

Strict-Transport-Security: max-age=300; includeSubDomains

5分間(300秒)HSTSを有効にし、サイトが正常に動作するか確認します。

ステップ2: 1週間に延長

Strict-Transport-Security: max-age=604800; includeSubDomains

1週間(604800秒)問題なく動作することを確認します。

ステップ3: 1年間に設定

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

問題がなければ、1年間に設定し、preloadオプションも追加します。

3. HSTSプリロードリストへの登録

HSTSには「初回訪問時は無防備」という問題があります。ユーザーが一度もそのサイトを訪れたことがなければ、HSTSヘッダーを受信しておらず、最初のアクセスはHTTPになる可能性があります。

この問題を解決するのが、HSTSプリロードリストです。Chrome、Firefox、Safari、Edgeなどのブラウザに、あらかじめHSTS対応サイトのリストを組み込むことで、初回訪問時から自動的にHTTPSでアクセスします。

登録条件

  1. 有効なHTTPS証明書
  2. すべてのHTTPトラフィックをHTTPSにリダイレクト
  3. すべてのサブドメインでHTTPSをサポート
  4. HSTSヘッダーに以下を含める:
    • max-ageが31536000(1年)以上
    • includeSubDomains
    • preload

登録手順

  1. 上記条件を満たしているか確認
  2. https://hstspreload.org/ にアクセス
  3. ドメイン名を入力し、チェック
  4. 問題がなければ送信

登録後、数ヶ月でChromiumのソースコードに追加され、各ブラウザに配布されます。

注意点

プリロードリストからの削除は非常に困難です。 一度登録すると、削除申請から実際に各ブラウザから消えるまで数ヶ月〜1年かかります。すべてのサブドメインで永続的にHTTPSをサポートできる確信がない限り、登録すべきではありません。

特に、以下のような場合は注意:

  • サブドメインで古いアプリケーションやデバイスが動作している
  • HTTPのみをサポートする必要のあるレガシーサービスがある
  • サブドメインの管理が分散している大企業

4. includeSubDomainsの注意点

includeSubDomainsを設定すると、すべてのサブドメインでHTTPSが必須になります。以下を確認してください:

  • すべてのサブドメインにSSL証明書がインストールされているか
  • 開発環境やステージング環境のサブドメイン(dev.example.comなど)もHTTPS対応か
  • 古いアプリケーションがHTTPのみで動作していないか

問題がある場合は、includeSubDomainsを外すか、問題のあるサブドメインに対してワイルドカード証明書を導入します。

5. テストと検証

設定後、以下を確認します:

# HSTSヘッダーを確認
curl -I https://example.com | grep Strict-Transport-Security

# 期待される出力
# Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

ブラウザでアクセスし、開発者ツール(F12)→「ネットワーク」タブでレスポンスヘッダーを確認します。

また、https://hstspreload.org/ でドメインをチェックし、プリロード登録の準備ができているか確認します。

まとめ

HSTSは、HTTPSを導入した後の「最後の穴」を塞ぐ重要な対策です。SSLストリッピング攻撃や、ユーザーのミスタイプによるHTTPアクセスを防ぎ、完全なHTTPS化を実現します。

設定は簡単で、HTTPSレスポンスに1行のヘッダーを追加するだけです。ただし、includeSubDomainsやpreloadリスト登録は慎重に行う必要があります。段階的にmax-ageを延ばし、問題がないことを確認してから、最終的に1年間に設定しましょう。

HTTPS + HSTSの組み合わせで、ウェブサイトの通信セキュリティは大幅に向上します。Nyambushの無料スキャンで、あなたのサイトのHSTS設定を確認してみてください。

この記事をシェア:Xでポスト

あなたのドメインは安全ですか?

Nyambushで今すぐ無料スキャンして、セキュリティリスクをチェックしましょう。