home ホーム search 検索 -  login ログイン  | reload edit datainfo version cmd icon diff delete  | help ヘルプ

読書メモ/「めんどうくさいWebセキュリティ」 (v1)

読書メモ/「めんどうくさいWebセキュリティ」 (v1)

読書メモ / 「めんどうくさいWebセキュリティ」 (v1)
id: 1240 所有者: msakamoto-sf    作成日: 2013-10-13 19:35:24
カテゴリ: HTTP Web セキュリティ 読書 

邦題:「めんどうくさいWebセキュリティ」(原著:"The Tangled Web: A Guide to Securing Modern Web Applications")

付箋挟んだ箇所のメモ書き。


以下、付箋メモ:

p37, 「もう一度、すべてをひとつに」の"NOTE"
"Internet ExplorerはURL中の任意の箇所でスラッシュの代わりにバックスラッシュ(\)を使用することができます。"
∑(゚Д゚) うそ~ん

p59, 「HTTP/0.9をサポートし続けていると……」
本文中の例だと、ブラウザは http://example.com:25/ とかに誘導されたのか?実際にローカルで実験用のSMTPサーバを立ちあげてアクセスしてみたところ、確かにSMTPサーバからのエラー文字列がブラウザ上に表示された。ただし、使用したSMTPサーバ( http://nilhcem.github.io/FakeSMTP/ )の仕様か、受け付けたコマンド文字列はエコーバックせず、エラーメッセージのみが表示された。

SMTPはあくまでも例であり、テキストベースのプロトコルを用いたサービス全般に対して、HTTP/0.9をサポートするUserAgentには同様の問題があると考えるべきか。

p59, 「改行文字の扱いにまつわる微妙な問題」

Set-Cookie: abc=[CR][CR]<html><body><h1>Hi[CR][LF]

→これ、適当なカスタムヘッダで試してみたけど、IE10で修正されたのか、ちゃんとCRCR以降は読み捨てされ、その後ろのHTMLコンテンツが表示されることは無かった。(F12による開発者コンソールで確認)
実験用ダミーサーバスクリプト(groovy):

char cr = 0x0d;
char lf = 0x0a;
StringBuilder sb = new StringBuilder();
sb.append(cr);
sb.append(lf);
String crlf = sb.toString();
sb = new StringBuilder();
sb.append(cr);
sb.append(cr);
String crcr = sb.toString();

def server = new ServerSocket(5000);
while(true) {
    server.accept() { socket ->
        socket.withStreams { input, output ->
            // ignore input and just serve dummy content
            output.withWriter { writer ->
                writer << "HTTP/1.1 200 OK" + crlf;
                writer << "Content-Type: text/html" + crlf;
                writer << "X-Custom-Header1: abc=def" + crcr + "hellohello<html><body><h1>Hi</h1></body>" + crlf;
                writer << "Pragma: nocache" + crlf + crlf;
                writer << "<html><body>Hello World! It's ${new Date()}</body></html>";
            }
        }
    }
}

64p, 「セミコロンで区切られたヘッダの値」
66p, 「ヘッダの文字セットとエンコーディングスキーム」
この辺は、アップロードされたファイルを、任意のファイル名でダウンロードするようなWebサイトを作った経験がある人なら大いに参考になりそう。「日本語ファイル名の扱い」という地雷もあるし、ブラウザのサポート状況などかなり悩ましい問題。"Content-Disposition"を扱う時はこのあたりを一読しておいて損はない。

68p, 「Refererヘッダの振る舞い」
Refererヘッダが含まれないのはどんな時か、というのが端的にまとめられているので、サーバ側でRefererヘッダを何かしらの処理に使う時は、一度さっと目を通しておくと良いかも。

79p,「キャッシュの振る舞い」
セキュリティを考慮する必要のない静的なコンテンツについてキャッシュさせたい、あるいは逆に、センシティブな情報を動的に出力するプログラムでキャッシュを無効化したい、などの場合に一読しておくと良いかも。また企業ネットワークで使う想定の場合、途中のProxyでのキャッシュも想定すると、HTTPSにするとかも必要かも。「スターバックスでPCを使ったあとには、ブラウザキャッシュを削除しておくというのは非常によい考え」・・・昨今ならスマホのブラウザのキャッシュも該当するかも?

81p,「HTTPクッキーのセマンティクス」
"HTTP仕様ではクッキー値はquoted-string形式を使用するものと述べられている(~)のに対して、この構文を実際に識別するのがFirefoxとOperaだけである点があります。"
う~ん・・・以下のスクリプトでFirefox 24.0 / IE 10.0 で試してみたが、いずれも引用符(0x22)含みのCookie、ちゃんと引用符として扱ってくれて、FFとIEで引用符の認識で差が出てるようには見えなかった・・・。ひとまず、スペース(0x20)含ませてみたところ、そこで終わりにせずちゃんとスペースの後ろまで値として認識してくれたのが面白かった(FF/IE共)。

def server = new ServerSocket(5000);
while(true) {
    server.accept() { socket ->
        socket.withStreams { input, output ->
            // ignore input and just serve dummy content
            output.withWriter { writer ->
                writer << "HTTP/1.1 200 OK\r\n";
                writer << "Content-Type: text/html\r\n";
                writer << "Set-Cookie: foo1=include space1\r\n";
                writer << "Set-Cookie: foo2=\"include space2\"\r\n";
                writer << "Set-Cookie: abc=\"12 3\\\"45 6\"\r\n";
                writer << "Set-Cookie: def=ABC\"DEF\r\n";
                writer << "\r\n";
                writer << "<html><body>Hello World! It's ${new Date()}";
                writer << "<script>alert(document.cookie);</script>\r\n";
                writer << "</body></html>";
            }
        }
    }
}

86p,「HTTP認証」
「~そのスレッドを閲覧しているユーザーには、いきなりよくわからないパスワード要求画面が表示されます。~」
こ、こえ~

91p,「セキュリティエンジニアリングチェック表」
→Content-DispositionヘッダーとSet-Cookieのセクションは読んでおいて損はない。

100p,「HTMLパーサーの振る舞いを理解する」
「おおっ!?」ってなったのが、

<img ... title=""onerror="alert(1)">

に続く、

<img ... title=``onerror=`alert(1)`>

の例。バッククォートも認識されるらしい。
・・・が、IE10で試してみたところ、以下のエラーが開発者ツールのコンソールに表示され、alert()は動作しなかった。
「HTML1410: 引用符で囲まれていない属性値が無効です。引用符で囲まれていない属性値に (")、(')、(<)、(=)、または (`) を含めることはできません。 」

IEの場合の等号("=")処理も驚き。

<img src=test.jpg?value=">Yes, we are still inside a tag!">

・・・だが、これもIE10で試したところ、互換モードを色々いじってみても">Yes, we are..."はちゃんとタグの外になり、属性としては認識されていない。

103p,「エンティティエンコーディング」(Entity Encoding)
HTMLの属性内でのEntityEncodingを行う場合は、ここのセクションに目を通しておく必要がありそう。
またXHTMLを使う場合はさらに注意が必要。

120p,「@ディレクティブとXBLバインディング」
FirefoxではXBLというのがあるんだ・・・。

144p,「標準オブジェクト階層」
「location.*データを使用して、新規に文字列(特にHTMLもしくはJavaScriptコード)を構築する際には、何らかの方法でこれがエスケープされていると仮定することは危険なので注意してください。」

151p,「スクリプトの文字エンコーディング」
「エスケープコードは識別子のなかでのみ使用可能であり、構文に影響をおよぼす記号を置き換えても動作はしません。」

\u0061lert("...");

→XSSを防ぐために、入り口でBlackList的に"alert"などの識別子をフィルタリングorブロックしようとすると、この仕様により簡単にすり抜けてしまう。

158p,「プレーンテキストファイル」
「JavaScriptの正式なMIMEタイプはapplication/javascriptです。これはRFC4329で規定されています。」
・・・ホンマや・・・。ってか、"application/ecmascript"(拡張子 ".es")というのもあるのか・・・。

192p,「document.domain」
えっ、document.domain って上書き出来るの!?
ただし、お互いに通信しようとする双方で合わせる必要があるらしい。

195p,「ブラウザの認証情報とのやり取り」
・・ここの、CSRFでログインさせ、「自傷行為」と呼ばれるXSS脆弱性を悪用するシナリオが、よく理解できません・・・。どこでどうSOPの同期状態が関連するのか?

196p,「XMLHttpRequestにおける同一生成元ポリシー」
XMLHttpRequestのsetRequestHeader()で設定できるヘッダと、BlackList対策について。

201p, 「クッキーのセキュリティポリシー」

Cookieのpath属性があてにならない「こともある」という表現が使われているが、path属性はあくまでもCookieの有効範囲でしか影響せず、JavaScriptのSOPはpath制限なんて無いためそちらで自由に触られる、という話か?path属性を指定していても役に立たない、具体的なケースがイメージ出来ない・・・。path属性の制限がブラウザによりぶっ壊れてる、とかなら分かりやすいのだけれど、JS側のSOPとの食い違いでどんな影響が出るのかが分からない。"http://asp.example.com/fooCompnay/" と "http://asp.example.com/barCompany/" とで、Cookieはpath属性で分離されてても、JSでのXHRなどは素通しされてしまう、というようなことを言っているのだろうか?

secure属性についても言及有り。HTTPとHTTPSで、同じ名前のCookieをsecure属性無し/有りで管理すると混乱しそう。

211p,「ポリシーフィアルとスニッフィングのリスク」

Adobeのcrossdomain.xml、およびMicrosoft Silverlightでの注意点について。

228p,「javascript:URLとvbscript:URLにおける継承」
いわゆる「ブックマークレット」で、アドレスバーでjavascript:スキームに遷移すると、遷移前のドキュメントのSOPでJavaScriptが動作しますが、それの危険性について。
遷移の方法によって、さらにブラウザによって、拒否したりSOPの継承もとが変化したりと複雑。

236p,「フレームハイジャック」
生成元とフレームの遷移に関する、鬱になるようなややこしい話題。ちなみに、ここではあくまでもフレーム間の遷移アクションについての解説になっており、「クリックジャッキング」については 240p からの「不要なフレーム表示」で解説されてる。

243p,「ドメインを超えたコンテンツのインクルード」
CSS構文解析でのフォールトトレランス性の高さに起因する、クロスドメインでCSSを読み込んだ場合に発生しうる重要情報の漏えいについて。
→ちょっとわかりづらかったので、解説されてるシナリオを噛み砕くとこういう状況で合ってるか?
1. サイトAでは、ログインしているユーザに紐づく重要情報を表示するページA-1があり、そこにはユーザが入力された文字列が表示される箇所がある。特にこのシナリオでは、URLパラメータに渡された文字列がレスポンスHTML中に出力される。
2. 上記ページA-1では、URLパラメータに渡す文字列を工夫することで、CSSとして誤って解釈した場合に、"background-image" のURLとして重要情報が含まれてしまうような挙動をしてしまう。
3. サイトBは攻撃者が用意した罠サイトで、サイトAのページA-1をわざとCSSとしてインクルードするようになっている。この時、2.で説明したようにして、"background-image" のURLで攻撃者のサイトを引っ張ってくるようにしておく。これにより、"background-image"のリソースをブラウザがロードする際に、攻撃者のサイト上のURLにアクセスすることになるが、URLの後ろにCSSとして誤って解釈された、重要情報のHTMLソースが付加されてしまう。
4. 攻撃者はサイトBに、被害者のブラウザを誘導する。
5. 被害者のブラウザが既にサイトAでログイン済みだった場合、CSSとしてページA-1を読み込む。「被害者に紐づく」重要情報が出力されたページA-1は、攻撃者が埋め込んでおいたURLパラメータにより誤ってCSSとして解釈され、"background-image" のURLをロードする際に、被害者に紐付いた重要情報をURLに付加して、攻撃者のサーバにリクエストを送信する。
6. 攻撃者は被害者の重要情報を不正に入手する。

268p, 「Content-Typeの特殊な値」
今度、ファイルを添付ファイルとしてDLさせるWebアプリを作る場合、今度は "application/octet-stream" ではなくて、"application/binary" を使おう・・・。
また、PATH_INFOによるコンテンツの誤認識にも注意。

292p,「ポップアップフィルタ」
最近は目にすること少なくなった・・・と思うんですが、なんかFacebookとかGoogleのOAuth認証使うサイトでたまに見たりします。
大分制限が加えられているようですが、この辺を扱う際は、ここを読んでおくと良さそうです。



プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2013-10-13 19:39:23
md5:03b3ee7847498a8c0cfbf21f8dab3a87
sha1:a53ab1080187c5a55fe830b8a54d5691d586af8d
コメント
コメントを投稿するにはログインして下さい。