HTTPに関するセキュリティリスクについて(その2)
GETメソッドとPOSTメソッドについて、なんとなく知っている相違点は次のようなものがあります。
・GETは文字数制限がありテキストデータしか送れない
・POSTは文字数制限がなくバイナリデータも送れる
GETとPOSTについてもう少し詳しく、どういった場面でGETとPOSTを使い分ければよいか見ていきましょう。
● GETについて
GETはURLのパスやパラメータを含めた情報をリクエスト行(最初の1行目)に格納して送信します。GETのリクエスト(サーバへの送信)ではメッセージボディは使用されません。
例:GETのリクエスト時のHTTPメッセージ
・Webサーバ側(apatchではLimitRequestLineのデフォルトが8190byte)で上限値が設定される
・Internet Explorerがブラウザ側で2083文字に制限している
<GETメソッドを使用した場合のセキュリティリスクについて>
・URL上のパラメータがアドレスバーに表示される
GETメソッドを使って通信した場合はリクエスト行に設定されたパラメータの内容がブラウザのアドレスバーに表示されます。
ブラウザのアドレスバーは常に表示されていることが多いので、秘匿情報が表示されていると本人以外の人に見られるリスクが高まります。
利用者はアドレスバーに表示されている情報が秘匿情報であることを認識していないことがあるため、Webアプリケーション側で秘匿情報を送信するときはGETを使用しないようにしましょう。
・パラメータ付きのURLを公開してしまう
アドレスバーのURLをそのままコピーしてメールやSNSなどに貼り付け、公開してしまうケースがあります。
アドレスバーに記載されているパラメータの値がパーセントエンコードされているなどして利用者はそれが秘匿情報だと認識できず、公開されたWeb上へリンクを貼りつけてしまい情報が漏れてしまうことがあります。
例えば、Web会議を行うために共有したURLにWeb会議室のIDとパスワードが追加されていた場合、そのURLを会議に無関係な人へ送ってしまうと会議の内容が外部へ漏えいしてしまう可能性があります。
社内イベントなどで多数の参加者がいるがIDとパスワードを共通にしている場合などは参加者のチェックが甘くなり侵入者に気が付かないことがあります。
利用者からすればログイン情報を入力する手間が省けるため便利なように見えますが、利用者が認識していないところに秘匿情報が存在していると情報漏えいのリスクが高くなるため、やはり秘匿情報を送信するときにGETは使用しないほうがよいでしょう。
・URLの内容がWebサーバのアクセスログに残る
Webサーバでは特に設定を変えない限りアクセスログを残す設定になっています。
デフォルトではリクエスト行を全て記録する設定になっているものが多いので、GETメソッドでの通信ではパラメータを含めてアクセスログに記録されることになります。
(POSTの場合はリクエスト行にパラメータが含まれないのでパラメータをログとして残したいときはアプリケーション側で対応する必要があります)
アクセスログを残すことは不具合の原因追跡やセキュリティ対策としても有効な手段ですが、利用者の秘匿情報が記録されることになるとアクセスログの流出に対して対策を取る必要があります。
リスクの高い情報がアクセスログに残らないように注意しましょう。
・パラメータがReferer経由で外部に流出する
例えば、ログインが必要なWebサービスの掲示板にリンクが貼られた投稿があり、利用者がそのリンクをクリックすると掲示板にGETでアクセスしたときの情報がリンク先のサーバのアクセスログにRefererとして記録されてしまいます。
その情報のなかに利用者の秘匿情報が記録されているとアクセス先のサーバの管理者に知られてしまうことになります。
現在の各ブラウザのデフォルト設定は下記のようです。
上記表のように現時点で主要なブラウザのRefererのデフォルト設定はstrict-origin-when-cross-origin になっています。
・リンク先が同じオリジンの場合は完全なURLを送る
・HTTPS → HTTPへはRefererを送らない
・上記以外はリンク元のオリジンのみ送る
オリジンとは、URLに含まれる「スキーム」「ホスト」「ポート番号」の組み合わせのことで、どれか一つでも違えばオリジン不一致となります。
HTTPSとHTTPではスキームが違うので不一致になります。つまり同じドメインでもHTTP → HTTPSではRefererはオリジンしか送られません。
主ブラウザの各社がRefererのデフォルト設定をstrict-origin-when-cross-originに変更したのはセキュリティ対策のためということですが、この対策により利用者がブラウザをアップデートすることでWebアプリケーションに影響が出るケースがあります。
例えば、Webページのアナリティクスでどのページから遷移されてきたのかを必要としている場合に、突然、正確なデータを取ることができなくなってしまいます。また、CSRF対策でRefererの値を見て正しい遷移を識別しているケースでは全て拒否されてしまうことも考えられます。
そのため、Refererをあてにした実装をしている箇所に影響が出てしまいます。
セキュリティの観点からはstrict-origin-when-cross-origin設定を変更することはお勧めできません。また、CSRF対策としてRefererは使用せずCSRFトークンを使用する方法が推奨されます。
Referer対策については各ブラウザがデフォルト設定を変更したことでWebアプリケーションの開発側には対応の影響がでてしまいますが、不用意なサイトから利用者の情報がRefererを通じて外部に流出するリスクは大幅に減ったと考えられます。
● POSTについて
POSTはパラメータをメッセージボディに格納して通信します。リクエスト行にパラメータが存在しないためGETのようにアドレスバーに表示されることはありません。
また、アクセスログにもパラメータは残らないため、ログ解析のためにパラメータを残したい場合はアプリケーション側でログとして出力する必要があります。
例:POSTのリクエスト時のHTTPメッセージ
POSTでは大きなサイズのメッセージを送ることが可能ですが、サーバリソースの制限やサイバー攻撃対策等により下記箇所で上限が設定されていることが多いです。
POSTデータのサイズ制限がかかる設定
POSTで設定値以上のデータを送信したい場合はシステムのパフォーマンスへ影響を与えないか考慮したうえでインフラエンジニア等に相談して計画的に設定を変更することになると思います。
<GETとPOSTの使い分け>
HTTP1.1を定義しているRFC7231のガイドラインでは次のように示されています。
・GETメソッドは参照(リソースの取得)のみに用いる
・GETメソッドは副作用がないことが期待される
・秘匿情報の送信にはPOSTメソッドを用いること
副作用とはリソース(コンテンツ)の取得以外の作用のことで、サーバ側での追加・更新・削除が起こる更新系の画面ではPOSTメソッドを使わなければならないことになります。
また秘匿情報を扱うところやデータ量が多い場合はPOSTメソッドを使ったほうが良いでしょう。
どちらを使うべきか迷った場合は、このガイドラインを参考にしてみてください。
その他、情報セキュリティに関する記事リンク
国家資格になった情報処理安全確保支援士を会社に所属させるメリットについて考える
【情報処理技術者試験に役立つ!】用語と解説をまとめたリンク集(PDFデータ付き)
非常に良い記事だと思いました。他の記事も良かったです。良いブログだと思います。
返信削除有難うございます!励みになります!
返信削除