この記事はseccamp2017 Advent Calendar 2017 の10日目です。記事の執筆から逃げていたら担当日が終わりそうで焦りながら書いています。
WebセキュリティではXSSやSQLi, CSRFなど比較的よく知られている脆弱性だと思います。これら以外にも様々な種類があることを最近、書籍(脆弱性診断スタートガイド)やWebで学んだので紹介してみます。
cookieのhttponly属性
cookieには属性という情報を付与することが出来ます。このうちのhttponly
属性はWebページ(HTML)からcookieに対してアクセス出来るかを表しています。この属性が有効になっている場合、JavaScriptを利用してcookieへアクセスすることが出来ません。
例えば、サイトにXSSの脆弱性がありcookieでセッションを管理していた場合、httponly
属性が有効でないとdocument.cookie
によりセッション情報が流出する危険性があります。これはセッションハイジャックなどにも繋がる可能性もあります。
この対策は、cookieのhttponly
属性を有効にすることです。ただし、Webサイトでcookieの情報を取得する場合 は有効にすると妨げになってしまうので注意が必要です。
参考: httpOnlyなCookieとは? – それマグで!
cookieのsecure属性
上記のhttponly属性と同様にcookieに付与する属性になります。これは本来、httpsでやり取りされるべきcookieがhttpでやり取りされるのを防ぐことが出来ます。なので、httpsサイトでは可能な限り付与するべきだと思います。
参考: http https 混在サイトでの Cookie Secure 属性の扱い方 – 長生村本郷Engineers’Blog
HTTPヘッダ・インジェクション
リクエストに含まれる改行コードがエスケープされずに出力されてhttpヘッダにインジェクションが可能になる脆弱性です。 例えば以下のパラメータ付きURLhttp://test.com/a.php?jump=%0d%0aLocation:%20http://yahoo.co.jp/
でyahoo.co.jpにリンクされてしまった場合、httpヘッダインジェクションが起きているといえます。
そこで実際に検証してみることにしました。実際に動かしてみたソースコードは以下です。
<?php if(isset($_GET['jump'])){ $dest=$_GET['jump']; }else{ $dest="default"; } header("HTTP/1.1 301 Moved Permanently"); header("Content-Type: text/html"); header("Location: http://koyama.me/?param=$dest"); exit; ?>
環境はapache + php7.0でdockerを使いました。実際にテストで送ったリクエストが以下です。
GET /test.php?jump=%0D%0ALocation:%20http://yahoo.co.jp/ HTTP/1.1 Host: localhost:8000 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:57.0) Gecko/20100101 Firefox/57.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Connection: close Upgrade-Insecure-Requests: 1
このリクエストに対してサーバからは以下のレスポンスが帰ってきました。
HTTP/1.1 301 Moved Permanently Date: Sun, 10 Dec 2017 14:46:04 GMT Server: Apache/2.4.10 (Debian) X-Powered-By: PHP/7.0.24 Content-Length: 149 Connection: close Content-Type: text/html;charset=UTF-8 <br /> <b>Warning</b>: Header may not contain more than a single header, new line detected in <b>/var/www/html/test.php</b> on line <b>11</b><br />
正直、これは本来意図していた応答ではありません。しかし、PHPのheader関数の内部でhttpヘッダインジェクション対策が行われているからこそでもあります。徳丸先生の記事が参考になります。
PHPにおけるHTTPヘッダインジェクションはまだしぶとく生き残る | 徳丸浩の日記
本来、意図したレスポンスは以下の形式です。
HTTP/1.1 301 Moved Permanently Date: Sun, 10 Dec 2017 14:45:43 GMT Server: Apache/2.4.10 (Debian) X-Powered-By: PHP/7.0.24 Location: http://koyama.me/?param= Location: http://yahoo.co.jp/ Content-Length: 0 Connection: close Content-Type: text/html;charset=UTF-8
このレスポンスを見るとhttpレスポンスのヘッダにLocation:
が複数並んでいることが確認できます。書籍によるとApacheでは複数あるLocation:
のうち最後に存在するものが優先されるとのことでした。実際に、手元の環境でも試したところ同様の挙動を確認することが出来ました。この挙動に関してもブラウザやサーバソフトウェアに依存すると思われます。もう少し詳しい検証が必要だと感じました。
時間がないので今回はこの辺で…。遅れてごめんなさいm(_ _)m
検証環境
- Docker(php:7.0-apache)
- Firefox 57.01(64bit)
- BurpSuite Community Edition 1.7.29
コメントを残す