有名事故・脆弱性7分で読める

Heartbleed(CVE-2014-0160)— OpenSSLの不具合でサーバーのメモリ内容が漏れた事件

Heartbleedは2014年に見つかったOpenSSLの脆弱性で、サーバーのメモリ内容が外部へ漏れ、秘密鍵やセッション情報まで抜かれうるものでした。仕組みと時系列、鍵と証明書を入れ替える教訓を解説します。

本文を読む
公開日
更新日
目次

過去の大きな事件を、いま自分の運用に効く教訓に絞って振り返ります。攻撃の再現ではなく、防御の視点で読み解きます。

2014
発覚した年
〜17%
公表時のSSL調査(信頼済み証明書)
秘密鍵
漏れえた最悪の中身
痕跡なし
検知の難しさ

何が起きたか:要求より多くのデータを返す不具合

TLS(HTTPSの暗号化)には、接続を維持するための「生存確認(ハートビート)」のやり取りがあります。クライアントが短いデータと「これを返して」という長さを送り、サーバーがそのまま返す。本来はそれだけの単純な仕組みです。

OpenSSLの実装は、この申告された長さを検証していませんでした。実際は数バイトしか送っていないのに「64KB返して」と申告すると、サーバーは送られた分を超えて隣接するメモリまで読み出して返してしまいます。そこに秘密鍵やセッションが乗っていれば、それも一緒に漏れる。

正常:送った長さ=返す長さ

「"bird"(4文字) を返して・長さ4」→ サーバー「bird」

↓ 申告長さを検証しないと…

Heartbleed:短い送信+大きな申告長さ

「"bird"(4文字) を返して・長さ64KB」→ サーバー「bird+隣のメモリ64KB(秘密鍵・セッション等を含みうる)」

本来は『送った分だけ返す』。Heartbleedは申告長さを信用し、隣のメモリまで返してしまった。

攻撃側に特別な権限は要りません。何度も繰り返すことでメモリの断片を少しずつ収集できました。非常に多くのソフトウェアが依存するTLSライブラリの小さなバグが、世界中のHTTPS通信の安全性に影響したのです。

痕跡が残りにくい漏洩は、範囲を特定できない

Heartbleedは通常のアクセスログに痕跡を残しにくく、「漏れたか」「何が漏れたか」を後から断定しづらいものでした。判断に迷ったら最悪を前提に動くのが正解です。

時系列

  1. 2014-04-07

    脆弱性が公表され、修正版OpenSSLが同時にリリースされる。
  2. 公表直後

    世界中のサーバーが一斉にパッチ適用へ。影響範囲の広さに騒然となる。
  3. その後

    多くのサービスが「秘密鍵が漏れた前提」で証明書を失効・再発行。利用者にパスワード変更を呼びかけた。

なぜパッチの適用だけでは終わらないのか

秘密鍵が漏れた可能性がある以上、パッチを当てても過去に漏れた鍵は有効なままです。だから対応は2段階です。脆弱性を修正する(パッチ)ことと、漏れた前提で鍵・証明書・秘密を入れ替えることです。

不十分な対応

  • OpenSSL を更新して「直した」と考える
  • 悪用が確認できた1つの秘密だけ替える
  • 証明書はそのまま使い続ける

正しい対応

  • 更新に加え、証明書を失効・再発行(秘密鍵を作り直す)
  • サーバーが持つ秘密・鍵・パスワードを総入れ替え
  • 利用者にパスワード変更を促す

いま効く教訓

1

「漏れたら全部漏れた」前提で動く

確認できた1個でなく、サーバーが持っていた秘密・鍵・パスワードを総入れ替えする。痕跡が残らない漏洩では、最悪を前提に動くのが安全。

2

証明書は失効・再発行する

秘密鍵が漏れた可能性があるなら、証明書も作り直す。鍵をローテーションしない限り、過去に漏れた鍵が使える状態のまま残る。

3

基盤となるライブラリも監視対象にする

アプリだけでなく、OpenSSL のような基盤ライブラリの CVE も機械監視で追う。多くのソフトが依存するものほど影響範囲が広い。

4

メモリ安全性の価値を理解する

「要求より多く読む」類のバグは、メモリ安全な設計・言語で構造的に減らせる。使う技術を選ぶときの観点に入れる。

次に読む

出典と確認範囲

以下は上記の設定・影響範囲・対策を確認するための原典です。2026年10月23日に参照先を確認しました。各版・構成の条件は原典で確認してください。チェックリストの優先順位や教訓は当サイトの整理であり、記事全体の再検証や安全性の保証を意味しません。

よくある質問

QHeartbleedで何が漏れた可能性があった?
A

サーバーのメモリ内容です。運が悪いとTLSの秘密鍵、セッションの中身、ログイン情報などが含まれ得ました。しかも漏洩は痕跡を残しにくく、『どこまで漏れたか』を後から特定しにくいのが厄介でした。

Qなぜ『要求より多く返す』ことが起きたの?
A

接続維持の確認(ハートビート)で、相手が申告した『返してほしい長さ』をサーバーが検証せず信用したためです。実際は短いデータしか送っていないのに『64KB返して』と申告すると、サーバーは隣接するメモリまで読み出して返してしまいました。入力(長さ)を検証せず信用したことが原因でした。

Q対応で一番大事だったことは?
A

パッチ後に『漏れた前提で動く』こと。具体的には、TLS証明書の失効・再発行と、サーバーが持っていた秘密・パスワードの総入れ替えです。アプリを直すだけでは不十分でした。