【入門編】HTTP/2におけるセキュリティ脆弱性:ストリーム多重化攻撃 – HTTPプロトコル・通信規格実践ガイド

こんにちは!ネットワークの世界へようこそ。インフラエンジニアの主筆ライターとして、日々飛び交うパケットのドラマをお届けしている私ですが、今回はWebブラウザとサーバーの裏側でこっそり繰り広げられている「ちょっと危ないお話」をしていきたいと思います。

私たちが何気なく見ているWebサイト。画像や文字がパパッと一瞬で表示されるのは、現代のWebを支える「HTTP/2」という仕組みのおかげです。このHTTP/2、実はものすごく仕事ができる優秀な優れものなのですが、その「優秀さ」ゆえのちょっとした弱点、そしてそれをどうやって守っているのかという現場の知恵があるんです。

難しい専門用語はなるべく避けて、身近な例え話から一歩ずつ紐解いていきましょう!

—

1. HTTP/2の「マルチプレクシング」ってなに?

まずは、HTTP/2の最大の特徴である「マルチプレクシング(多重化)」についてお話ししますね。

これまでの古い仕組み(HTTP/1.1)を、「1通ずつしか手紙を送れない真面目な郵便配達員」に例えてみましょう。この配達員さんは、Aさん宛ての荷物を届けに行って、それが終わるまで次のBさんの荷物を運ぶことができませんでした。Webページには画像やアイコンが何十個もありますから、配達員さんは何度も往復して、大忙しです。

これでは効率が悪いということで登場したのが、HTTP/2の「マルチプレクシング」です。これは例えるなら、「一度にたくさんの引き出し(ストリーム)が作れるスーパーカバンを持った配達員さん」です。

1本の通信回線(道路)の中に、いくつもの独立したレーン(ストリーム)を作って、画像も文字も全部の荷物を同時にピュッと送り出せるようになりました。「同時にいろんなやり取りができるなんて、なんて画期的なんだろう!」と思いますよね。

—

2. 便利さの裏に潜む罠:ストリーム多重化攻撃

さて、ここからが今回の本題です。この「同時にたくさんのストリームを開ける」という便利な機能、実は悪意を持った攻撃者からすると格好の標的になってしまうんです。

これを「ストリーム多重化攻撃(Stream Multiplexing Attack)」、あるいは「HTTP/2の資源枯渇攻撃(Resource Exhaustion Attack)」などと呼びます。

どんな攻撃かというと、先ほどの配達員さんの例えで言うと、「悪意のあるお客さんが、同時に1万個もの空っぽの引き出しをムリヤリ開けさせた挙句、中身を全然入れない嫌がらせ」をするようなものです。

サーバーは、「おっ、たくさんのお客さんからリクエストが来たぞ!それぞれの引き出しの準備をしなきゃ!」と、メモリやCPUなどの大切なリソースをフル回転させて対応しようとします。しかし、中身は空っぽか、あるいはわざとノロノロとしかデータを送ってきません。

これを何千、何万という規模でやられたらどうなるでしょうか?
サーバーは、開けられた無数の空っぽの引き出しの管理だけで手一杯になり、本当に買い物をしたい一般のお客さんのリクエストを処理できなくなってしまいます。これが、サーバーがダウンしてしまう「リソース枯渇(サービス停止:DoS)」のメカニズムです。

便利な道具も、使い方を間違えたり悪意に使われたりすると、大きな弱点になってしまうんですよね。

—

3. サーバーを守る切り札:`SETTINGS_MAX_CONCURRENT_STREAMS`

「うわぁ、それじゃあHTTP/2って怖くて使えないんじゃ……?」と思ったそこのあなた、ご安心ください!ちゃんと現場のエンジニアや規格を作った人たちは、この対策を用意しています。

それが、`SETTINGS_MAX_CONCURRENT_STREAMS`(同時ストリーム数の上限設定)というパラメーターです。

これは先ほどの郵便配達員の例えで言うなら、サーバー側がこう宣言するルールです。
> 「うちの窓口では、1人のお客さんが同時に開けられる引き出しは、最大でも『100個』までね!それ以上は一度に受け付けません!」

このように、1つの接続(コネクション)の中で同時に処理できるストリームの数に「上限(制限)」を設けることで、サーバーのメモリやCPUがパンクするのを防ぐわけですね。攻撃者がいくら何万個もの引き出しを開けようとしても、サーバーが「いや、100個までなんで無理です!」とピシャリと拒否できるため、リソースを安全に守ることができます。

—

4. 実務で設定してみよう(Nginxの例)

それでは、実際にWebサーバー(今回はよく使われるNginxを例にします)で、この制限をどのように設定するのか、現場のコードを見てみましょう。

難しいことはありません。設定ファイルに一行書き加えるだけです。一緒に見ていきましょう!

Nginxの設定ファイルのイメージ (nginx.conf など)
http {
# HTTP/2を有効にするための設定(ポート443のsslブロックなどで指定)
server {
listen 443 ssl http2;
server_name example.com;

# SSL証明書のパスなどは省略…

# ==========================================
# ここが今回の主役!同時ストリーム数の制限設定
# ==========================================
# 1つの接続(コネクション)あたり、同時に処理するストリームの最大数を「128」に制限します。
# デフォルトより小さめに設定することで、多重化攻撃によるメモリ枯渇を防ぐ盾になります。
http2_max_concurrent_streams 128;

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

このように、実務の現場ではサーバーのスペックや想定するアクセスの規模に合わせて、この `http2_max_concurrent_streams`(Nginxの場合)などの値を調整し、安全な運用を行っています。

—

おわりに

今回は、HTTP/2の便利な仕組みである「マルチプレクシング」の裏側にあるリスクと、それを守るための「`SETTINGS_MAX_CONCURRENT_STREAMS`」という防衛策についてお話ししました。

ネットワークの技術は、便利さと安全性のバランスを取る歴史の連続です。「どうすればもっと速く通信できるか」を考えるだけでなく、「どうすれば悪意ある攻撃からサーバーを守れるか」という視点を持つことで、インフラやプロトコルを見る目がぐっと面白くなっていきます。

ぜひ、身の回りのWeb技術の裏側にある「優しいルール」にも注目してみてくださいね。それでは、また次回の技術散歩でお会いしましょう!

コメント

タイトルとURLをコピーしました