【情報処理安全確保支援士】HTTPに関するセキュリティリスクについて(その1):HTTPヘッダインジェクション

2021年11月26日金曜日

HTTP セキュリティ 情報処理安全確保支援士

t f B! P L


 HTTPに関するセキュリティリスクについて(その1)




Webアクセスする際に日常的に使われるHTTPについて情報セキュリティの観点から考えていきたいと思います。


HTTPメッセージ

 HTTPを使った通信で送信(リクエスト)、返信(レスポンス)する際のメッセージの構造はメッセージヘッダとメッセージボディを空行でくっつけたテキストになります。

 メッセージヘッダの一部として、リクエストの場合は最初の1行がリクエスト行になり、レスポンスの場合は最初の1行がステータス行になります。


※リクエスト行とステータス行はメッセージヘッダの一部です




例えば、Chromeで開発ツール(F12)を開いてジープラのページへアクセスし、Network項目でwww.yahoo.jpのHeadersをみてみるとHTTPメッセージヘッダの中身を確認することができます。





メッセージヘッダでは1行(改行コードまで)で一つの意味を持ちます。

これらの情報はHTTP/1.1ではテキストデータで作成されhttp通信でそのまま平文で送信されます。

そのため、暗号化されていないhttp通信では盗聴、改ざんが容易に行われてしまいます。

 HTTP/2http通信は対応ブラウザが無いため事実上https限定、HTTP/3QUICが使われておりhttps通信が必須のため暗号化されて送信されます)

 

開発環境では証明書の管理やコストの面からスピード感を重視してhttp通信で進行することがありますが、最近のWebアプリケーションでは外部のWebサービスを利用・連携するケースも多々あるので、外部に公開しなければならない場合はインフラエンジニアと相談して適切な方法をとる必要があります。

 

また、https通信であってもHTTPメッセージの仕様を悪用した手口を使われ、アクセスするWebページに脆弱性がある場合はHTTPヘッダインジェクションという攻撃を受けることがあります。


■HTTPヘッダインジェクション

手口としては、脆弱性のあるWebサイトへアクセスするためのURLを攻撃者が作成し対象者にそのURLのリンクを使ってGETでアクセスさせます。その際、正当なパラメータの値に不正な入力を行っておくことでレスポンスのメッセージに不正コードが仕込まれてしまいます。


Webアプリケーションのサーバ側でレスポンスヘッダの値を直接指定するページはそれほど多くはないと思いますが、比較的発生しやすいのがLocationヘッダを指定してリダイレクトさせるページです。


ページのリニューアル等で新しいページへアクセスを向けさせる必要があるときや、UX向上のためにログインをはさんでユーザーの指定したページへリダイレクトさせるケースなどがあります。


※注意
次にあげる例について、PHPではHTTPヘッダインジェクション対策がされているため再現することは難しいです。古いバージョンのPHPを使用していたり対策をされていない言語を使っているWebアプリケーションでは少し変更を加えるだけで再現できてしまうことがありますが、今回例にあげるような通信ケースを公開されているWebアプリケーションで見かけても絶対に試してみたりしないでください。


●HTTPヘッダインジェクションの例


例:www.test.jp/sample.php?page=top



例えば、sampleのページにアクセスするとsample-newのページへリダイレクトさせたい場合、sampleページへアクセスされたときのパラメータをそのまま引き継ぐためにsample-newページのURLに対してパラメータの値を受け取ったままのデータでLocationヘッダに指定してしまうと次のような攻撃を受ける可能性があります。




・悪意のあるWebページ(フィッシングサイト等)へリダイレクトされる

例: www.test.jp/sample.php?page⁼top[改行コード]Location:(攻撃者が用意したURL)



このケースの場合は、pageパラメタの値をsample-newページへのリダイレクトのためにLocationヘッダへsample-newページへのURLの後ろにそのまま追加して書き込みます。

レスポンスヘッダに2つのLocationヘッダが出力されることになりますが、Apacheは受け取ったヘッダ中にLocationヘッダが複数あると最後のLocationヘッダのみをレスポンスとして返すため、本来のリダイレクト先URLは消えてしまい攻撃者が用意したURLのLocationヘッダを返してしまいます。

その結果、利用者が攻撃者の用意したフィッシングサイトへアクセスしてしまいます。

また、返信データに正規のWebアプリケーション側で利用者の識別情報やセッションIDなどを付加していると、その情報は攻撃者の用意したサーバへ送信されてしまいます。




・Cookieを書き換えられる

例: www.test.jp/sample.php?page⁼top[改行コード]Set-Cookie:(攻撃者が用意した値)




この場合、利用者はsample-newのページへ遷移できますがレスポンスヘッダに攻撃者が用意したSet-Cookieヘッダが追加されてしまいます。
その結果、受信した利用者のブラウザに攻撃者が用意したCookieのIDと値の組み合わせが設定されてしまいます。

 Cookieを攻撃者が用意した任意の値に書き換えられることでセッションIDの固定化などの攻撃を受け、なりすまし等の被害をうける可能性があります。

  セッションIDの固定化攻撃に対するWebアプリケーション側の脆弱性としては、セッションが切れた状態でログイン画面にアクセスし、ログイン後にセッションを確立する場合にログイン画面の時点で生成したセッションIDをそのままログイン後も同じセッションIDを使用してしまっているケースがあります。

ログイン前後で同じセッションIDを使っているかどうかは簡単に確認することができてしまうため狙われやすいです。


例えば、セッションが切れてログイン画面にリダイレクトされた際、ログインするためのCookieに設定されたセッションIDが攻撃者の用意したセッションIDに書き換えられていると、利用者が行ったログイン成立後のアクセスは攻撃者の用意したセッションIDで行われることになるため、攻撃者は自分のPCから同じセッションIDで利用者になりすますことができます。

このような脆弱性をなくすためには、ログイン成立後は新しいセッションIDを生成して通信を確立するほうがよいでしょう。




・偽の画面が表示されてしまう

例:www.test.jp/sample.php?page⁼top[改行コード] [改行コード](攻撃者が用意した偽のページのHTML)



レスポンスヘッダに改行コードを2つ入れることで、空行を作りそのあとに攻撃者の用意した偽ページのHTMLデータが挿入されます。

  レスポンスヘッダとメッセージボディを分けるのは最初の空行になるので、この場合のHTTPレスポンスは上記の表のようになります

このままだと表示されるページは、攻撃者の用意した偽画面の下に元のページが表示されますが、攻撃者がCSSを工夫することで元のページを隠して偽ページの画面を表示させることができてしまいます。

正規ドメイン内のページ表示になるため、JavaScriptを実行させることで利用者のCookieの値を攻撃者宛てにメールで送信して盗むこともできてしまいます。
フィッシングサイトのように偽のフォームを表示して個人情報を入力させ送信させる手口に利用されるケースもあります。



●HTTPヘッダインジェクション脆弱性への対策


基本的な対策は「外部からのパラメータをHTTPレスポンスヘッダとして出力しない」ことが重要になります。

方法としては、

・リダイレクト先のURLを固定にするか番号で指定する

レスポンスヘッダに設定する値を動的に生成しないことで安全な値を返すことができます


・パラメータの受け渡しにセッション変数を使用する

レスポンスヘッダを介さないのでHTTPヘッダインジェクション脆弱性を回避することができます。ただし、セッション変数はCookieを利用するのでそちらの管理は別に考慮する必要があります。


・開発言語に用意されている専用APIを利用してHTTPヘッダを出力する

HTTPインジェクション脆弱性の対策が行われているライブラリ機能を介すことで安全にレスポンスヘッダを作成することができます。

しかし、言語やバージョンによっては完全な対策とはいえないものもあるため自衛手段を講じておくことも重要になります。
(PHPでは環境によってはvar5.6以下だとheader関数を使っても対策が漏れることがあります)


・ヘッダ生成するパラメタの改行文字をチェックする

APIによっては改行をチェックしないものもあるため、自衛のため次のような処理を自身で行っておくことも重要になります。

「URLの値に改行があればエラーにする」
「Cookieの値にある改行はパーセントエンコードする」


Webアプリケーションでサーバ側がレスポンスヘッダを作成して出力するケースは、リダイレクトとCookie生成が多いと思いますが、HTTPヘッダインジェクションに限らず外部から受け取ったパラメータをチェックせずにそのままレスポンスとして返すことは他の脆弱性を生み出すことになりかねないので注意してください。


Webブラウザ側の処理でプルダウン数字入力制限などにより正常範囲の入力しかできないように対処してあっても、送信者が自身の送信データを改ざんすることはフリーのツールを使用することで容易にできてしまいます。hiddenパラメータに設定してある値であっても同様に利用者による書き換えは容易です。


データを受け取ったサーバ側でライブラリ機能による対策が万全であるか、チェック機能を組み込む必要があるかを確認するようにしましょう。


次回:「GETとPOSTの違いとセキュリティ上の注意点」




このブログを検索

ブログをよくする

自己紹介

自分の写真
はじめまして。はるはるです。 中2の息子と小5の娘を抱える2児の父です。今はゲーム会社で働いています。 子供のプログラミング学習に協力できるように教え方を勉強中です。 このブログでは簡単なゲームを作りながら自分が学んだことを少しずつ共有していきます。 情報処理の試験をたまに受けます。 第二種情報処理技術者 ソフトウェア開発技術者 基本情報処理技術者 応用情報処理技術者 twitter: https://twitter.com/amaruchan007

連絡フォーム

名前

メール *

メッセージ *

ブログ アーカイブ

QooQ