歴史
Heartbleed(CVE-2014-0160)— 暗号通信の土台から記憶が漏れた事件
2014年、世界中のHTTPS通信を支えるOpenSSLに、サーバーのメモリ内容が外部へ漏れる脆弱性Heartbleedが見つかりました。秘密鍵やセッション情報まで抜かれうる深刻さ、なぜ起きたのかの仕組み図解、時系列、そして『漏れたら全部漏れた前提で動く』『鍵と証明書を入れ替える』という、いまも変わらない教訓を、図と表で解説します。
過去の大きな事件を、いま自分の運用に効く教訓に絞って振り返ります。攻撃の再現ではなく、防御の視点で読み解きます。
何が起きたか — 「要求より多く返してしまう」
TLS(HTTPSの暗号化)には、接続を維持するための「生存確認(ハートビート)」のやり取りがあります。クライアントが短いデータと「これを返して」という長さを送り、サーバーがそのまま返す——本来はそれだけの単純な仕組みです。
OpenSSLの実装は、この申告された長さを検証していませんでした。実際は数バイトしか送っていないのに「64KB返して」と申告すると、サーバーは送られた分を超えて隣接するメモリまで読み出して返してしまいます。そこに秘密鍵やセッションが乗っていれば、それも一緒に漏れる。
正常:送った長さ=返す長さ
「"bird"(4文字) を返して・長さ4」→ サーバー「bird」
Heartbleed:短い送信+大きな申告長さ
「"bird"(4文字) を返して・長さ64KB」→ サーバー「bird+隣のメモリ64KB(秘密鍵・セッション等を含みうる)」
攻撃側に特別な権限は要りません。何度も繰り返すことでメモリの断片を少しずつ収集できました。土台中の土台であるTLSライブラリの小さなバグが、全世界の通信の信頼を揺るがしたのです。
“痕跡が残らない漏洩”の怖さ
Heartbleedは通常のアクセスログに痕跡を残しにくく、「漏れたか」「何が漏れたか」を後から断定しづらいものでした。判断に迷ったら最悪を前提に動くのが正解です。
時系列
2014-04-07
脆弱性が公表され、修正版OpenSSLが同時にリリースされる。公表直後
世界中のサーバーが一斉にパッチ適用へ。影響範囲の広さに騒然となる。その後
多くのサービスが「秘密鍵が漏れた前提」で証明書を失効・再発行。利用者にパスワード変更を呼びかけた。
なぜ「パッチだけ」では終わらないのか
秘密鍵が漏れた可能性がある以上、パッチを当てても過去に漏れた鍵は有効なままです。だから対応は二段構え——穴を塞ぐ(パッチ)+漏れた前提で資産を入れ替える(鍵・証明書・秘密)。
不十分な対応
- OpenSSL を更新して「直した」と考える
- 悪用が確認できた1つの秘密だけ替える
- 証明書はそのまま使い続ける
正しい対応
- 更新に加え、証明書を失効・再発行(秘密鍵を作り直す)
- サーバーが持つ秘密・鍵・パスワードを総入れ替え
- 利用者にパスワード変更を促す
いま効く教訓
「漏れたら全部漏れた」前提で動く
確認できた1個でなく、サーバーが持っていた秘密・鍵・パスワードを総入れ替えする。痕跡が残らない漏洩では、最悪を前提に動くのが安全。
証明書は失効・再発行する
秘密鍵が漏れた可能性があるなら、証明書も作り直す。鍵をローテーションしない限り、過去の漏れが生き続ける。
“土台ソフト”も監視対象にする
アプリだけでなく、OpenSSL のような土台の CVE も機械監視で追う。土台ほど影響範囲が広い。
メモリ安全性の価値を理解する
「要求より多く読む」類のバグは、メモリ安全な設計・言語で構造的に減らせる。土台選びの観点に入れる。
次に読む
- 用語:CVE とは
- 事故:.env 公開で全シークレットが漏れた話
- 入門:秘密の守り方・超入門
よくある質問
QHeartbleedで何が漏れた可能性があった?
サーバーのメモリ内容です。運が悪いとTLSの秘密鍵、セッションの中身、ログイン情報などが含まれ得ました。しかも漏洩は痕跡を残しにくく、『どこまで漏れたか』を後から特定しにくいのが厄介でした。
Qなぜ『要求より多く返す』ことが起きたの?
接続維持の確認(ハートビート)で、相手が申告した『返してほしい長さ』をサーバーが検証せず信用したためです。実際は短いデータしか送っていないのに『64KB返して』と申告すると、サーバーは隣接するメモリまで読み出して返してしまいました。入力(長さ)を信用したことが穴でした。
Q対応で一番大事だったことは?
パッチ後に『漏れた前提で動く』こと。具体的には、TLS証明書の失効・再発行と、サーバーが持っていた秘密・パスワードの総入れ替えです。アプリを直すだけでは不十分でした。