HTML5セキュリティ その2: オープンリダイレクト、CSRF - UTF-8.jp

Download Report

Transcript HTML5セキュリティ その2: オープンリダイレクト、CSRF - 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オブジェクトへ の代入

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/

#owaspjapan

OWASP Japan Local Chapter Meeting #8

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) #owaspjapan

OWASP Japan Local Chapter Meeting #8

IE6,7のは癖がある

「;」より後ろのURLが転送先に使用される

「;」をエスケープしても防げない

によるリダイレクトの動 的生成は避けたほうがよい

#owaspjapan

OWASP Japan Local Chapter Meeting #8

オープンリダイレクトを防ぐために

転送先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により攻撃しやすくなった

攻撃対象 : ファイルのアップロードフォーム

OWASP Japan Local Chapter Meeting #8

#owaspjapan

CSRF

従来の攻撃手法

罠ページではformを自動でsubmitする

これではファイルの中身は送信できない

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

対策

従来同様、副作用を持つ全ての箇所にトーク ンを要求する

#owaspjapan

OWASP Japan Local Chapter Meeting #8

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対策

罠サイトからの

によるPOSTで はX-Requested-Withリクエストヘッダ は付与されない

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必須

と違いページ遷移しない

DNS rebinding対策必須

#owaspjapan

OWASP Japan Local Chapter Meeting #8

まとめ

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