utf-8.jp

HTML5 and Security
Part 2: Open redirect and CSRF
HTML5セキュリティ その2 : オープンリダイレクト、CSRF
Nov 14 2013
Yosuke HASEGAWA
#owaspjapan
自己紹介
はせがわようすけ
ネットエージェント株式会社
株式会社セキュアスカイ・テクノロジー 技術顧問
Microsoft MVP for Consumer Security Oct 2005 http://utf-8.jp/
OWASP Japan Local Chapter Meeting #8
#owaspjapan
お知らせ
announcement
HTML5 調査報告 from JPCERT/CC
OWASP Japan Local Chapter Meeting #8
#owaspjapan
オープンリダイレクト
Open redirect
Open redirect
オープンリダイレクト
本来はWebサイト内でのリダイレクト機能
http://example.jp/go?url=/next/page.html
攻撃者の指定した任意のサイトへジャンプで
きてしまう
http://example.jp/go?url=http://evil.example.com/
フィッシングやSEOポイゾニングに使用され
る
サイト自体に被害を与えるわけではない
サイトの信頼は損ねる
OWASP Japan Local Chapter Meeting #8
#owaspjapan
Open redirect
オープンリダイレクト
実在した例
site:www.microsoft.com/japan/ adult
OWASP Japan Local Chapter Meeting #8
#owaspjapan
Open redirect
オープンリダイレクト
リダイレクトの方法
HTTP応答として301または302を返す
JavaScriptによるlocationオブジェクトへ
の代入
<meta refresh>
OWASP Japan Local Chapter Meeting #8
#owaspjapan
Redirect with 301 or 302
脆弱な例
オープンリダイレクトだけでなくHTTPヘッ
ダインジェクションもある。
#!/usr/bin/perl
use URI::Escape;
my $url = uri_unescape( $ENV{QUERY_STRING} || '/' );
print "Status: 302 Found\n";
print "Location: $url\n\n";
HTTP/1.1 302 Found
Date: Tue, 28 Feb 2013 12:34:56 GMT
Location: http://other.example.jp/
OWASP Japan Local Chapter Meeting #8
#owaspjapan
location with JavaScript
JavaScriptによるリダイレクト
JavaScriptコード増に伴い増加
// http://example.jp/#/nextpage
var url =
decodeURIComponent( location.hash.substring(1) );
location.href = url;
オープンリダイレクトだけでなくXSSにも
http://example.jp/#javascript:alert(1)
OWASP Japan Local Chapter Meeting #8
#owaspjapan
<meta refresh>
IE6,7の<meta refresh>は癖がある
「;」より後ろのURLが転送先に使用される
<meta http-equiv="refresh"
content="0;url=http://good/;url=http://evil/">
「;」をエスケープしても防げない
<meta http-equiv="refresh"
content="0;url=http://good/&#x3b;url=http://evil/">
<meta refresh>によるリダイレクトの動
的生成は避けたほうがよい
OWASP Japan Local Chapter Meeting #8
#owaspjapan
オープンリダイレクトを防ぐために
転送先URLの確認…実は難しいよね
http://example.com/
//example.com/
http:\\example.com/
http:/\example.com
/\example.com/
その他にもいろいろ
if( url.match( /^\/[^\/]/ ) ){
location.href = url;
} // bad code
OWASP Japan Local Chapter Meeting #8
#owaspjapan
オープンリダイレクトを防ぐために
HTTPレスポンスヘッダの改行コード
ブラウザによっては\r、\nどちらかだけで
も改行とみなされる
X-header: foo(0x0D 0x0A)Location: http://example.com/
X-header: foo(0x0D)Location: http://example.com/
X-header: foo(0x0A)Location: http://example.com/
OWASP Japan Local Chapter Meeting #8
#owaspjapan
オープンリダイレクトを防ぐために
根本的対策
転送先URLを事前にリストとして保持
#!/usr/bin/perl
use URI::Escape;
my $index = uri_unescape( $ENV{QUERY_STRING} || '' );
my $pages = { foo=>'/foo', bar=>'/bar', baz=>'/baz' };
my $url = $pages->{$index} || '/';
print "Status: 302 Found\n";
print "Location: $url\n\n";
// JavaScriptによるリダイレクト
var pages = { foo:'/foo', bar:'/bar', baz:'/baz' };
var url = pages[ location.hash.substring(1) ] || '/';
location.href = url;
OWASP Japan Local Chapter Meeting #8
#owaspjapan
CSRF
CSRF
XHR Lv.2により攻撃しやすくなった
攻撃対象 : ファイルのアップロードフォーム
<form method="POST" action="upload"
enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit">
</form>
OWASP Japan Local Chapter Meeting #8
#owaspjapan
CSRF
従来の攻撃手法
罠ページではformを自動でsubmitする
<body onload="document.forms[0].submit();">
<form method="POST"
action="http://target.example.jp/upload"
enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit">
</form>
</body>
これではファイルの中身は送信できない
OWASP Japan Local Chapter Meeting #8
#owaspjapan
CSRF
XHR Lv.2によるCSRF攻撃
var xhr = new XMLHttpRequest();
var boundary = '----boundary';
var file="abcd";
//送信するファイルの内容
var request;
xhr.open( 'POST', 'http://target.example.jp/upload', 'true' );
xhr.setRequestHeader( 'Content-Type',
'multipart/form-data; boundary=' + boundary );
xhr.withCredentials = true;
// Cookieを付与
xhr.onreadystatechange = function(){};
request = '--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="file"; ' +
' filename="filename.txt"\r\n' +
'Content-Type: application/octet-stream\r\n\r\n' +
file +
'\r\n' + '--' + boundary + '--';
xhr.send( request );
OWASP Japan Local Chapter Meeting #8
#owaspjapan
CSRF
XHR Lv.2によるCSRF攻撃
XHRではクロスオリジンでリクエストを発行
可能(サーバ側が非対応でも送信は可能)
Content-Typeおよび送信内容をJavaScript
で組み立てて発行(バイナリも可)
従来不可能だったファイルのアップロードの
CSRFが攻略可能になった
OWASP Japan Local Chapter Meeting #8
#owaspjapan
CSRF
対策
従来同様、副作用を持つ全ての箇所にトーク
ンを要求する
<form method="POST" action="upload"
enctype="multipart/form-data">
<input type="file" name="file">
<input type="hidden"
name="token" value="2ACE730295E23F2C">
<input type="submit">
</form>
OWASP Japan Local Chapter Meeting #8
#owaspjapan
HTM5時代のCSRF対策
HTML5時代のCSRF対策
XMLHttpRequestを明示するリクエスト
ヘッダを付与(これだけ!!)
xhr = new XMLHttpRequest();
xhr.open( "POST", "/inquiry", true );
xhr.setRequestHeader( "Content-Type", "..." );
xhr.setRequestHeader(
"X-Requested-With","XMLHttpRequest");
xhr.send( params );
POST http://example.jp/inquiry HTTP/1.1
Host: example.jp
UserAgent: Mozilla/5.0
X-Requested-With: XMLHttpRequest
Content-Type: application/x-www-form-urlencoded
OWASP Japan Local Chapter Meeting #8
#owaspjapan
HTML5時代のCSRF対策
罠サイトからの<form>によるPOSTで
はX-Requested-Withリクエストヘッダ
は付与されない
<body onload="javascript:forms[0].submit()">
<form method="POST"
action="http://example.jp/inquiry">
<input type="hidden" value="...">
</form>
POST http://example.jp/inquiry HTTP/1.1
Host: example.jp
UserAgent: Mozilla/5.0
Referer: http://trap.example.com/
Content-Type: application/x-www-form-urlencoded
OWASP Japan Local Chapter Meeting #8
#owaspjapan
HTML5時代のCSRF対策
罠サイトからのXHRによるPOSTでは罠サ
イトを指すOriginヘッダを持つPreflightリ
クエストが発行される
xhr = new XMLHttpRequest();
xhr.open( "POST", "http:/example.jp/inquiry", true );
xhr.setRequestHeader( "Content-Type", "..." );
xhr.setRequestHeader(
"X-Requested-With","XMLHttpRequest");
xhr.send( params );
OPTIONS /inquiry HTTP/1.1
Host: example.jp
UserAgent: Mozilla/5.0
Origin: http://trap.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Requested-With
OWASP Japan Local Chapter Meeting #8
#owaspjapan
HTML5時代のCSRF対策
サーバ側でX-Requested-Withヘッダと
Originヘッダを確認することでCSRF対策
が可能
セッションの保持が不要
クロスドメインPOSTでのCSRF対策も可能
JavaScript必須
<form>と違いページ遷移しない
DNS rebinding対策必須
OWASP Japan Local Chapter Meeting #8
#owaspjapan
まとめ
Conclusion
まとめ
オープンリダイレクト
JSによるオープンリダイレクトが増加傾向
転送先URLを事前に固定リストで保持
CSRF
JSによってファイルアップロードが可能
XHRではセッションなしにCSRF対策可能
OWASP Japan Local Chapter Meeting #8
#owaspjapan
質問タイム
Question ?
Question?
質問
[email protected]
[email protected]
@hasegawayosuke
http://utf-8.jp/
OWASP Japan Local Chapter Meeting #8
#owaspjapan