プログラム最終更新日:2023/08/07ラムネグから一言:寝る前に読むとくだらなすぎて逆に寝れると好評なすごい適当なブログをこっちではじめてます.laravelの説明書読んでてイマイチピンとこなかったのがこれ。デフォルトでは、LaravelはHTTPリクエストのhostヘッダの内容に関係なく受信したすべてのリクエストにレスポンスします。Webリクエスト中にアプリケーションへの絶対URLを生成するときに、hostヘッダの値を使用します。引用:https://readouble.com/laravel/10.x/ja/passwords.htmlいったい何を言ってるんだ?と思ってたらどうやら「ホストヘッダインジェクション攻撃」と呼ばれるものに関する脆弱性を書いているみたい。ここではホストヘッダインジェクション攻撃ってなに?っていうのを書きます。「ホストヘッダインジェクション攻撃」っていうのを簡単に書くと「HTTP通信でやり取りされるHOSTヘッダを改ざんする攻撃」という事になります。HOSTヘッダっていうのは、WEBを見る側、つまり閲覧者側が、サーバに対して「僕このサービスにアクセスしたいな」って閲覧したいサイトのURLを書く場所なんです。このラムネグを見てくれてる人でいうならHOSTヘッダには勝手に「blog.dododori.com」と入っているわけです。これは閲覧してる側が任意に替えれるのですごく簡単に改ざんできる、と。通常HOSTヘッダに何が書かれてても関係ないんで改ざんされても痛くもかゆくもないんです。話飛んで「パスワードを忘れた」の話ここで話が飛びますが、アマゾンでもなんでもログイン機能のあるサイトだと何度かログインに失敗すると「パスワードを忘れた」っていうボタンが出てきますよね。「パスワードを忘れた」を押すと登録時のメールアドレスの入力を求められて、んで入力するとそのメールアドレスにパスワードリセット用のメールがリンク付きで届く、的な。あるやつなので皆さん1回くらいはお世話になったことがあると思います。このパスワードリセット機能でlaravelだと問題があるっぽいこの一見すると全く関係のない「ホストヘッダインジェクション攻撃」と「パスワードリセット」が合わさると脆弱性が出てくる、というのが重要になります。この記事の一番最初に書いたlaravelの説明で、「Webリクエスト中にアプリケーションへの絶対URLを生成するときに、hostヘッダの値を使用します。」というのがあります。これの言わんとしてることは、「パスワードを忘れた」で「ユーザーに送るメールのパスワードリセット用のリンクを作るときにこのHOSTヘッダの値使うからね!」って事...みたい。登場人物laravel.com:ログイン機能のある普通のサイト悪井さん:悪い人warui.com:悪井さんが用意したダミーサイト普通さん:laravel.comに登録している普通の人。悪井さん「ふっふっふ、このlaravel.comっていうサイトはログイン機能があるぞ!しかもlaravelじゃねぇか。悪井さん「とりあえずlaravel.comのパスワードを忘れたボタンをクリックしてっと。メールアドレスには普通さんのメールアドレスを入力。おっと、HOSTヘッダはオレの作ったwarui.comに書き換えて、っと。」laravel.com「あらあら、まあまあ、普通さんたらパスワードを忘れてしまったのね。普通さん「あれ?laravel.comからメールだ。なになに?パスワードリセット?うーん、確かに最近パスワード変えてなかったからなぁ...、入力しておくか。普通さん「んじゃ普段使ってるやつでいいや。悪井さん「へへへっ...、これで普通さんが使ってるパスワードをGETできたわけだ!」という。流れで漏洩するんですね。解りやすくなったでしょうか。HOSTヘッダからリンクを作るのか疑問すぎる結局キモはなぜいくらでも改ざんできるHOSTヘッダの値でパスワード再設定用リンクを作っちゃうのか、っていう部分。これをしてなければそもそもホストヘッダインジェクション攻撃なんて成り立たないんですよね。HOSTヘッダの情報なんて使わなくても、そもそもそのサーバ上で動いているのがそのWEBサービス(今回で言うとlaravel.com)なんだから自分のアドレスをそのまま使えばいいのに、本当に謎仕様すぎて理解ができません。laravelの他の認証システムは大丈夫なの?laravelにはログイン機能を作るための方法が4つくらいあります。Jetstream名前も全部ややこしいことこの上ないんですよねこれ。login-kit」みたいなわかりやすい名前にしておいて欲しいです。一応説明しておくと上から順番に機能が少なくなっていて「Fortify」は画面の見た目とかは自分で作らないといけません。「Breeze」は入れるだけでログイン機能が全部入ります。「Jetstream」はさらに機能が豊富でよくわかりませんがいろいろついてるやつです。このホストヘッダインジェクション攻撃に関して、とりあえずBreezeしか今の所使ってませんが特に対策されているようには見えません。うーん、それでいいのかな、laravel。実際は見えないところで対策されてるのかもしれませんが上の説明書で書いてある「TrustHostsミドルウェア」も有効になってなかったし、よくわかりません。「ホストヘッダインジェクション攻撃」対策laravelでは上記説明書によると「TrustHostsミドルウェア」を有効にすればHOSTヘッダの確認をしてくれるようになる(だからなんで自サーバのアドレスをそのまま使わないんだろう...)んですが、そのほかにもapacheでホストヘッダインジェクション攻撃対策をする事もできるみたい。apacheのバーチャルホスト機能を使うみたいです。まとめlaravelのログイン機能、それからホストヘッダインジェクション攻撃について書きました。まとめるとなんでHOSTヘッダなんていう改ざんし放題の値をパスワードリセット用のURL生成に使ってるのかマジイミフ!っていう感じです。laravel以外にもDockerとかにもそういう仕様というか脆弱性みたいなのがある(あった?)みたいですが、逆にHOSTヘッダの情報からリンクを作成するどこにメリットがあるんでしょう...?本当によくわかりません。今までlaravelではメール認証のログインシステムを一度も作ったことがない(ツイッター認証の「わたガチャ」「みんガチャ」「litty」の3つのみ)ので気にしてませんでしたが、けっこう面倒そうです。