Web::Security beyond HTML5 Sep 28 2012 Yosuke HASEGAWA
謝罪 「HTML5」関係ないです Perlのコードも出てきません
自己紹介 はせがわようすけ ネットエージェント株式会社 株式会社セキュアスカイ・テクノロジー 技術顧問 Microsoft MVP for Consumer Security Oct 2005 - http://utf-8.jp/
これまでに調べた脆弱性 Webブラウザ、Webアプリケーションを中心にいろいろ… CVE-2007-0995 XSS of Mozilla Firefox CVE-2007-1262 XSS of SquirrelMail CVE-2007-2227 XSS of Internet Explorer CVE-2008-0416 XSS of Mozilla Firefox CVE-2008-1468 XSS of Namazu CVE-2008-5808 XSS of Movable Type CVE-2010-1213 Cross-origin data disclosure of Mozilla Firefox CVE-2010-3348 Cross-origin data disclosure of Internet Explorer CVE-2010-3770 XSS of Mozilla Firefox CVE-2011-1339 XSS of Google Search Appliance CVE-2011-3384 XSS of Sage CVE-2011-3648 XSS of Mozilla Firefox ...
難読化 JavaScript Obfuscated JavaScript
記号JavaScript JS without alnum $=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:({}+"")[$],$$_:++$,$$$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$$=($.$+"")[$.__$])+((!$)+"")[$._$$]+($.__=$.$_[$.$$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$$=$.$+(!""+"")[$._$$]+$.__+$._+$.$+$.$$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$$+"\""+$.$_$_+(![]+"")[$._$_]+$.$$$_+"\\"+$.__$+$.$$_+$._$_+$.__+"(\\\"\\"+$.__$+$.__$+$.___+$.$$$_+(![]+"")[$._$_]+(![]+"")[$._$_]+$._$+",\\"+$.$__+$.___+"\\"+$.__$+$.__$+$._$_+$.$_$_+"\\"+$.__$+$.$$_+$.$$_+$.$_$_+"\\"+$.__$+$._$_+$._$$+$.$$__+"\\"+$.__$+$.$$_+$._$_+"\\"+$.__$+$.$_$+$.__$+"\\"+$.__$+$.$$_+$.___+$.__+"\\\"\\"+$.$__+$.___+")"+"\"")())(); jjencode - http://utf-8.jp/public/jjencode.html
顔文字JavaScript JS with emoticons ゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o - (゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+ ((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚) [゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)a+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚) [゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚) [゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚) [゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_'); aaencode - http://utf-8.jp/public/aaencode.html
質問 Question
質問 : Web技術、好きですか? Q. Do you love web technologies?
質問 : Web技術、好きですか? Q. Do you love web technologies? クロスサイトスクリプティング 強制ブラウズ 書式文字列攻撃 リモートファイルインクルード SQLインジェクション LDAPインジェクション バッファオーバーフロー パストラバーサル CSRF 質問 : Web技術、好きですか? Q. Do you love web technologies? セッションハイジャック OSコマンドインジェクション オープンリダイレクタ セッション固定攻撃 DoS メモリリーク HTTPレスポンス分割 HTTPヘッダインジェクション XPathインジェクション
Web技術、好きですか? 「はい」に挙手した人 かなり打たれ強い or 攻撃者
今日のはなし Today's topic
今日のはなし ぼくはPerlほとんどわかりません!
今日のはなし 最近見かけた脆弱性のはなし ブラウザの保護機構 Ajaxデータを利用した攻撃 XHR Level.2の注意点 XSSフィルター/XSS Auditor Content-Typeの強制 クリックジャッキング対策 Content-Security-Policy HTTPSの強制
今日のはなし 最近見かけた脆弱性のはなし ブラウザの保護機構 Ajaxデータを利用した攻撃 XHR Level.2の注意点 XSSフィルター/XSS Auditor Content-Typeの強制 クリックジャッキング対策 Content-Security-Policy HTTPSの強制
Ajaxデータを利用した攻撃 Ajaxの利用増加 Ajaxデータを利用したXSS Ajaxデータの盗み見 Webアプリケーションの高機能化 Ajaxデータ(JSON,text, csv etc..)を直接ブラウザ上で開いたときにXSS Ajaxデータの盗み見 機密情報を含むAjaxデータを受動的攻撃により攻撃者が盗み見る
Ajaxデータを利用した攻撃 Ajaxの利用増加 Ajaxデータを利用したXSS Ajaxデータの盗み見 Webアプリケーションの高機能化 Ajaxデータ(JSON,text, csv etc..)を直接ブラウザ上で開いたときにXSS Ajaxデータの盗み見 機密情報を含むAjaxデータを受動的攻撃により攻撃者が盗み見る
Ajaxデータを利用したXSS Ajaxデータを直接開いてXSS IEのContent-Type無視 HTMLではないものがHTMLに昇格してXSS 例えばtext/plain
Ajaxデータを利用したXSS IEは最終的に「ファイルタイプ」に基づいてコンテンツを処理する Content-Type 以外にも様々な要因からファイルタイプを決定 文書化されていない複雑なメカニズム 「ファイルのダウンロードダイアログで表示されるファイル名の命名規則」http://support.microsoft.com/kb/436153/ja ファイルタイプ決定のメカニズム解明に近づく唯一のドキュメント
Ajaxデータを利用したXSS ファイルタイプの決定因子 "Content-Type" HTTPレスポンスヘッダ "X-Content-Type-Option" HTTPレスポンスヘッダ Windowsレジストリにおける関連付け IEの設定:"拡張子ではなく、内容によってファイルを開く" URL自身 コンテンツそのもの
IEにおけるファイルタイプ決定のメカニズム Content-Typeがレジストリに登録されている? [ HKEY_CLASSES_ROOT\MIME\Database\Content Type ] Y N ファイルタイプを仮決定 IE8+ && "X-Content-Type-Options:nosniff"? Y N Y 外部プラグイン/アプリが必要? プラグインを起動またはダウンロード ダウンロード N Y IE8+ && "X-Content-Type-Options:nosniff"? 仮決定したファイルタイプを使用 N 「拡張子ではなく、内容によってファイルを開く」設定値 有効 コンテンツをsniffしファイルタイプを決定 無効 仮決定したファイルタイプを使用 URLの拡張子が ".cgi" または ".exe" または "/" ? e.g. http://utf-8.jp/a.cgi?abcd, http://utf-8.jp/foo/ Y N QUERY_STRINGからファイルタイプを 仮決定 URLの拡張子からファイルタイプを 仮決定 外部プラグイン/アプリが必要? 外部プラグイン/アプリが必要? N Y N Y コンテンツをsniffし ファイルタイプを決定 プラグインを起動 またはダウンロード コンテンツをsniffし ファイルタイプを決定 プラグインを起動 またはダウンロード ※これ以外にも例外的な挙動が多数あり Yosuke HASEGAWA http://utf-8.jp/
Ajaxデータを利用したXSS ファイルタイプ決定のメカニズムは、とにかく複雑すぎる! そもそも例外的な挙動が多い いつのまにか挙動が変化していることも多い Microsoft自身も挙動を把握しきれていないのでは
Ajaxデータを利用したXSS XSS実例 https://www.microsoft.com/en-us/homepage/ bimapping.js/a.html?v=<script>alert(1)</script>&k... HTTP/1.1 200 OK Content-Type: text/javascript; charset=utf-8 Date: Wed, 22 Jun 2011 13:53:37 GMT Content-Length: 2092 var <script>alert(1)</script>={"Webtrends":{"enabled":true,"sett ings":{"interactiontype":{"0":true,"1":true,"2":true,"3":true,"4":t rue,"5":true,"6":true,"7":true,"8":true,"9":true,"10":true,"11":tr ue,"12":true,"13".... "text/javascript" はレジストリに未登録
Ajaxデータを利用したXSS XSS実例
Ajaxデータを利用したXSS AjaxコンテンツによるXSSは以下のような状況で発生しやすい JSON - JSON文字列内 {"text" :"<script>..." } JSONP - callback名 http://example.com/?callback=<script>... text, CSV - そもそもエスケープできない
Ajaxデータを利用したXSS JSON - JSON文字列内 Content-Type: application/json; charset=utf-8 { "txt" : "<script>alert(1);</script>" } "application/javascript" はレジストリに未登録
Ajaxデータを利用したXSS JSONP – callback名 http://example.com/?callback=<script>alert(1);</script> Content-Type: text/javascript; charset=utf-8 <script>alert(1)</script>( { "name" : "value" } ); "text/javascript" はレジストリに未登録
Ajaxデータを利用したXSS text, csv – そもそもエスケープできない Content-Type: text/plain; charset=utf-8 これはテキストファイルです。<script>alert(1)</script> "text/plain" はsniff対象 Content-Type: text/csv; charset=utf-8 1,2,"abcd","<script>alert(1)</script>" "text/csv" はレジストリに未登録
Ajaxデータを利用したXSS Ajaxデータ内に<script>を埋め込む Ajaxデータを直接開いたときにHTML扱い JSON, JSONP, CSV, text など Ajaxデータを直接開いたときにHTML扱い IEのContent-Type無視が原因 対策の話はあとで。
Ajaxデータを利用した攻撃 Ajaxの利用増加 Ajaxデータを利用したXSS Ajaxデータの盗み見 Webアプリケーションの高機能化 Ajaxデータ(JSON,text, csv etc..)を直接ブラウザ上で開いたときにXSS Ajaxデータの盗み見 機密情報を含むAjaxデータを受動的攻撃により攻撃者が盗み見る
Ajaxデータの盗み見 JavaScriptとして解釈可能なAjaxデータが狙われやすい JavaScriptのsrcとして読み込む <script src="target.json"></script> <script src="target.csv"></script> JSON {"from" : "a@example.com"}
Ajaxデータの盗み見 様々な手法でブラウザごとにJSONデータを奪取 JSON以外にもCSVなどは狙いやすい JSON Array Hijacking for Android JSON Hijacking for IE JSON以外にもCSVなどは狙いやすい <script src="target.csv">
Ajaxデータの盗み見 様々な手法でブラウザごとにJSONデータを奪取 JSON以外にもCSVなどは狙いやすい JSON Array Hijacking for Android JSON Hijacking for IE JSON以外にもCSVなどは狙いやすい <script src="target.csv">
Array Hijacking for Android Androidでは、古いJSON Hijackingの手法がまた通用する PC用ブラウザでは2008年頃にはすでに根絶 Android 2.2, 2.3で確認 property setter の再定義 機密情報を含むJSON配列がターゲット
Array Hijacking for Android [ { "name" : "alice", "mail" : "alice@example.com" }, { "name" : "bob", "mail" : "bob@example.jp" }, ] 攻撃対象となるJSON : http://example.jp/target.json <script type="text/javascript"> var s = ""; Object.prototype.__defineSetter__( "mail", function( val ) { s += "mail:" + val + "\n"; } ); Object.prototype.__defineSetter__( "name", function( val ) { s += "name:" + val + "\n"; } ); </script> <script src="http://example.jp/target.json"></script> 攻撃者の作成した罠ページ
Ajaxデータの盗み見 様々な手法でブラウザごとにJSONデータを奪取 JSON以外にもCSVなどは狙いやすい JSON Array Hijacking for Android JSON Hijacking for IE JSON以外にもCSVなどは狙いやすい <script src="target.csv">
JSON Hijacking for IE IE6,IE7では特定条件下でJSONの奪取が可能 攻撃者がJSON内に文字列を挿入可能
JSON Hijacking for IE [ { "name" : "abc+MPv/fwAiAH0AXQA7-var t+AD0AWwB7ACIAIg-:+ACI-", "mail" : "hasegawa@utf-8.jp" }, "name" : "John Smith", "mail" : "john@example.com" } ] 攻撃者によって挿入 ターゲットとなるJSON : http://example.com/newmail.json
JSON Hijacking for IE [ { "name" : "abc"}];var t=[{"":"", "mail" : "hasegawa@utf-8.jp" }, "name" : "John Smith", "mail" : "john@example.com" } ] ターゲットとなるJSON : http://example.com/newmail.json
JSON Hijacking for IE 攻撃者は罠ページを準備して誘導 <script src="http://example.com/newmail.json" charset="utf-7"> <script> alert( t[ 1 ].name + t[ 1 ].mail ); </script> ターゲットとなるJSON http://example.com/newmail.json [ { "name" : "abc"}];var t=[{"":"", "mail" : "hasegawa@utf-8.jp" }, "name" : "John Smith", "mail" : "john@example.com" } ] [ { "name" : "abc+MPv/fwAiAH0AXQA7-var t+AD0AWwB7ACIAIg-:+ACI-", "mail" : "hasegawa@utf-8.jp" }, "name" : "John Smith", "mail" : "john@example.com" } ]
JSON Hijacking for IE 攻撃者の準備した罠ページ 攻撃者対象のJSON <script src="http://example.com/newmail.json" charset="utf-7"> こっちが優先される 攻撃者対象のJSON Content-Type: application/json; charset=utf-8 [ { "name" : "abc+MPv/fwAiAH0AXQA7-var t+AD0AWwB7ACIAIg-:+ACI-", "mail" : "hasegawa@utf-8.jp" }, "name" : "John Smith", "mail" : "john@example.com" } ]
JSON Hijacking for IE IE6,IE7はHTTPレスポンスヘッダより<script>要素のcharset属性を優先 IE8では修正されている 2008年10月に報告したが修正されない
Ajaxデータを利用した攻撃 Ajaxデータを利用した攻撃 対策 Ajaxデータを利用したXSS Ajaxデータ(JSON,text, csv etc..)を直接ブラウザ上で開いたときにXSS Ajaxデータの盗み見 機密情報を含むAjaxデータを受動的攻撃により攻撃者が盗み見る 対策 X-Content-Type-Options: nosniffヘッダ XMLHttpRequest以外からのアクセスを弾く エスケープ(XSS対策),POST限定(盗み見対策)なども次善策として…
Ajaxデータを利用した攻撃への対策 X-Content-Type-Optoins:nosniff XSS対策 レスポンスヘッダで応答 IE8以降でHTML扱いされることがなくなる IE6,7には効果なし Content-Type: application/json; charset=utf-8 X-Content-Type-Options: nosniff
Ajaxデータを利用した攻撃への対策 XMLHttpRequest以外からのアクセスを弾く Ajaxデータは通常、XHRからのリクエストを想定している XHR以外からアクセスさせないことでXSSおよび盗み見を防ぐことができる
Ajaxデータを利用した攻撃への対策 XMLHttpRequest以外からのアクセスを弾く リクエストヘッダに特定文字列を入れる GET http://example.jp/foo.json HTTP/1.1 Host: example.jp Connection: keep-alive X-Request-With: XMLHttpRequest User-Agent: Mozilla/5.0 (Windows NT 6.0; rv:8.0) jQuery、prototype.js だと X-Request-With は自動挿入される
Ajaxデータを利用した攻撃への対策 汎用的なWAFなど XHR経由のリクエストだけとは限らない POST限定にはできない 泥臭い対策が必要
Ajaxデータを利用した攻撃への対策 例: Amon2
Ajaxデータを利用した攻撃への対策 JSONの過剰エスケープ "<>+" を "\u003c\u003e\u002b" に 下記条件を満たす場合は403を返す 「GET リクエストである」かつ 「Cookie ヘッダを送信している」かつ 「/android/i にマッチする User-Agent ヘッダを付与している」かつ 「X-Requested-With ヘッダを付与していない」 http://blog.64p.org/entry/20111125/1322185155
今日のはなし 最近見かけた脆弱性のはなし ブラウザの保護機構 Ajaxデータを利用した攻撃 XHR Level.2の注意点 XSSフィルター/XSS Auditor Content-Typeの強制 クリックジャッキング対策 Content-Security-Policy
XHR Lv.2 XMLHttpRequest かつては同一オリジンへのリクエストしかできなかった プロトコル + ホスト + ポート var xhr = new XMLHttpRequest(); xhr.open( "GET", "http://example.jp/", true ); xhr.onreadystatechange = function(){ if( xhr.readyState == 4 && xhr.status == 200 ){ alert( xhr.responseText ); } xhr.send( null );
XHR Lv.2 XMLHttpRequest 現在はクロスドメインでのリクエストが可能 HTML GET / HTTP/1.1 base.example.jp another.example.jp HTML GET / HTTP/1.1 Host: another.example.jp Origin: http://base.example.jp/ HTTP/1.1 200 OK Access-Control-Allow-Origin: *
XHR Lv.2 現在のXMLHttpRequestは任意のサーバと通信可能 特定相手とのみ通信する場合はクライアント側、サーバ側双方で注意が必要
XHR Lv.2 クライアント側:DOM based XSS 自サイトとの通信を想定 サーバはHTML断片を返す innerHTMLにXHR.responseTextを代入 XHRの送信先が任意に指定可能な脆弱性
XHR Lv.2 典型的なコード // bad code: http://example.jp/#/foo/bar.txt var url = location.hash.substring(1); var xhr = new XMLHttpRequest(); xhr.open( "GET", url, true ); xhr.onreadystatechange = function(){ if( xhr.readyState == 4 && xhr.status == 200 ){ div.innerHTML = xhr.responseText; } xhr.send( null ); http://example.jp/#//evil.example.jp/ などの指定で任意コンテンツを挿入可能
XHR Lv.2
XHR Lv.2 XHRを利用する側は、任意ドメインからのデータを読まないようにチェック // http://example.jp/#/foo/bar.txt var url = location.hash.substring(1); if( url.match( ??????? ) ){ var xhr = new XMLHttpRequest(); xhr.open( "GET", url, true ); ... } url.match( /^\// ) // NG : #//evil.example.jp/ url.match( /^\/[^\/]/ ) // NG : #/\evil.example.jp/ url.match( /^\/\w/ ) // OK : #/foo/
XHR Lv.2 URLの確認は実はめんどうくさい。 詳細は「めんどうくさいWebセキュリティ」参照
XHR Lv.2 むしろXHRの宛先は固定で保持するべき var pages = [ "/", "/foo", "/bar", "/baz" ]; var index = location.hash.substring(1) | 0; var xhr = new XMLHttpRequest(); xhr.open( "GET", pages[ index ], true );
XHR Lv.2 サーバ側:特定の相手にのみ応答を許可 サーバ側はリクエストのOriginヘッダを見て相手を判別してはいけない GET / HTTP/1.1 Host: another.example.jp Origin: http://base.example.jp/ HTTP/1.1 200 OK Access-Control-Allow-Origin: htp://base.example.jp リクエスト レスポンス
XHR Lv.2 サーバ側:特定の相手にのみ応答を許可。 JSで明示的に指定した場合のみCookieが送信される xhr.withCredentials = true; // JavaScript内 GET / HTTP/1.1 Host: another.example.jp Origin: http://base.example.jp/ Cookie: sessionid=A251BBCA HTTP/1.1 200 OK Access-Control-Allow-Origin: htp://base.example.jp Access-Control-Allow-Credentials: true リクエスト レスポンス
XHR Lv.2 サーバ側:特定の相手にのみ応答を許可。 リクエストヘッダに「秘密の情報」を含める サーバ側はリクエストヘッダ内の情報を確認して正規の通信相手か判断 クロスドメインでのsetRequestHeaderは癖があるので注意 事前にOPTIONS要求が発行(preflight) https://developer.mozilla.org/en/http_access_control xhr.setRequestHeader( "X-Secret-Key", "A251BBCA" );
XHR Lv.2 クロスドメインでのpreflightリクエスト xhr.setRequestHeader( "X-Secret-Key", "A251BBCA" ); OPTIONS / HTTP/1.1 Host: another.example.jp Origin: http://base.example.jp/ Access-Control-Request-Method: GET Access-Control-Request-Headers: X-Secret-Key HTTP/1.1 200 OK Access-Control-Allow-Origin: htp://base.example.jp Access-Control-Allow-Methods: GET Access-Control-Allow-Headers: X-Secret-Key リクエスト レスポンス
XHR Lv.2 クロスドメインでのpreflightリクエスト Plack::Middleware::CrossOrigin xhr.setRequestHeader( "X-Secret-Key", "A251BBCA" ); builder { enable 'CrossOrigin', origins => '*', methods => ['GET'], headers => X-Secret-Key'; }
今日のはなし 最近見かけた脆弱性のはなし ブラウザの保護機構 Ajaxデータを利用した攻撃 XHR Level.2の注意点 XSSフィルター/XSS Auditor Content-Typeの強制 クリックジャッキング対策 Content-Security-Policy HTTPSの強制
XSSフィルター / XSS Auditor 反射型のXSSをほぼ軽減 IE8+、Chrome、Safari (WebKit)に搭載 リクエストとレスポンス両方に同一のスクリプトが含まれる場合にブロック
XSSフィルター / XSS Auditor レスポンスヘッダに の指定でフィルタを停止可能 レスポンスヘッダに の指定でフィルタを停止可能 誤検知の実害が出ていない場合は指定なし(XSSフィルタ有効)をおすすめ WebKitのXSS AuditorはXSSを検出してもユーザへの通知なし X-XSS-Protection: 0
今日のはなし 最近見かけた脆弱性のはなし ブラウザの保護機構 Ajaxデータを利用した攻撃 XHR Level.2の注意点 XSSフィルター/XSS Auditor Content-Typeの強制 クリックジャッキング対策 Content-Security-Policy HTTPSの強制
X-Content-Type-Options コンテンツ内の "sniff" を行わなくなる IE8+で有効 レスポンスヘッダに以下をつける 原則、全てのコンテンツにつけておくべき。 X-Content-Type-Options: nosniff
X-Content-Type-Options コンテンツ内の "sniff" を行わなくなる IE8+で有効 レスポンスヘッダに以下をつける 原則、全てのコンテンツにつけておくべき。 X-Content-Type-Options: nosniff
今日のはなし 最近見かけた脆弱性のはなし ブラウザの保護機構 Ajaxデータを利用した攻撃 XHR Level.2の注意点 XSSフィルター/XSS Auditor Content-Typeの強制 クリックジャッキング対策 Content-Security-Policy HTTPSの強制
クリックジャッキング対策 クリックジャッキング 標的サイトを透明に重ね、意図しないクリック等を引き起こす攻撃 透明表示の 標的サイト クリック!! 罠サイト
クリックジャッキング対策 frameおよびiframeでの表示を禁止する IE8+、Chrome、Safari、Opera、Firefoxの各ブラウザが対応 レスポンスヘッダで指定 // 全ての埋め込みを禁止 X-Frame-Options: DENY // 同一オリジン以外からの埋め込みを禁止 X-Frame-Options: SAMEORIGIN http://www.jpcert.or.jp/ed/2009/ed090001.pdf
今日のはなし 最近見かけた脆弱性のはなし ブラウザの保護機構 Ajaxデータを利用した攻撃 XHR Level.2の注意点 XSSフィルター/XSS Auditor Content-Typeの強制 クリックジャッキング対策 Content-Security-Policy HTTPSの強制
Content Security Policy Content-Security-Policy(CSP) XSS根絶の切り札 指定された以外のリソースが読めない <script><img><iframe>... インラインスクリプトが禁止される <script>alert(1)</script> … NG evalやイベント属性が禁止される <body onload=alert(1)> … NG
Content Security Policy Content-Security-Policy(CSP) 規格、実装が不安定 レスポンスヘッダで許可するリソースを指定 <meta>でも指定可。上書きは不可。 Content-Security-Policy: directive; // W3C X-Content-Security-Policy: directive; // Firefox X-WebKit-CSP: directive; // Chrome http://www.w3.org/TR/2012/WD-CSP-20120710/ http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html
Content Security Policy Content-Security-Policy(CSP) 許可するリソースを記述 'self'は同一ドメイン、同一ポートのみ許可 Content-Security-Policy: default-src 'self'
Content Security Policy Content-Security-Policy(CSP) リソースの種別ごとに指定可能 // 画像以外を同一ドメインに制約 Content-Security-Policy: default-src 'self'; image-src * // example.jp の script src を許可 Content-Security-Policy: default-src 'self'; script-src example.jp
今日のはなし 最近見かけた脆弱性のはなし ブラウザの保護機構 Ajaxデータを利用した攻撃 XHR Level.2の注意点 XSSフィルター/XSS Auditor Content-Typeの強制 クリックジャッキング対策 Content-Security-Policy HTTPSの強制
HTTPSの強制 HSTS - HTTP Strict Transport Security HTTPとHTTPS、両方を提供しているサイトで、HTTPSの使用を強制する機能 中間者攻撃の低減に Google Chrome、Firefoxが対応
HTTPSの強制 HTTPSのレスポンスヘッダで以下を返す これ以降のHTTPへのアクセスはHTTPSに置き換わる max-age は有効期間を秒数で指定 includeSubDomainsが指定されるとサブドメインも対象 Strict-Transport-Security: max-age=15768000 Strict-Transport-Security: max-age=15768000 ; includeSubDomanis
HTTPSの強制 HTTPSサイトのみがStrict-Transport-Securityを返す HTTPはすでに汚染されているかもしれないので Strict-Transport-Security: max-age=15768000
今日のはなし 最近見かけた脆弱性のはなし ブラウザの保護機構 Ajaxデータを利用した攻撃 XHR Level.2の注意点 XSSフィルター/XSS Auditor Content-Typeの強制 クリックジャッキング対策 Content-Security-Policy HTTPSの強制
まとめ
まとめ Ajax関連の脆弱性はブラウザ起因が多い 新しいブラウザには多数の保護機能 よい実装を広めてほしい!! Android 2.x、IE6-8 古いブラウザは直らない!サーバ側で対策 新しいブラウザには多数の保護機能 使えるものはどんどん取り込もう よい実装を広めてほしい!!
質問タイム
質問 hasegawa@utf-8.jp hasegawa@netagent.co.jp @hasegawayosuke http://utf-8.jp/