Your SlideShare is downloading. ×
文字コードの脆弱性はこの3年間でどの程度対策されたか?
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

文字コードの脆弱性はこの3年間でどの程度対策されたか?

22,665
views

Published on

Published in: Technology

0 Comments
57 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
22,665
On Slideshare
0
From Embeds
0
Number of Embeds
15
Actions
Shares
0
Downloads
0
Comments
0
Likes
57
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. 文字コードの脆弱性は この3年間でどの程度対策されたか? 2014年2月19日 徳丸 浩
  • 2. 徳丸浩の自己紹介 • 経歴 – 1985年 京セラ株式会社入社 – 1995年 京セラコミュニケーションシステム株式会社(KCCS)に出向・転籍 – 2008年 KCCS退職、HASHコンサルティング株式会社設立 • 経験したこと – 京セラ入社当時はCAD、計算幾何学、数値シミュレーションなどを担当 – その後、企業向けパッケージソフトの企画・開発・事業化を担当 – 1999年から、携帯電話向けインフラ、プラットフォームの企画・開発を担当 Webアプリケーションのセキュリティ問題に直面、研究、社内展開、寄稿などを開始 – 2004年にKCCS社内ベンチャーとしてWebアプリケーションセキュリティ事業を立ち 上げ • 現在 – HASHコンサルティング株式会社 代表 http://www.hash-c.co.jp/ – 独立行政法人情報処理推進機構 非常勤研究員 http://www.ipa.go.jp/security/ – 著書「体系的に学ぶ 安全なWebアプリケーションの作り方」(2011年3月) – 技術士(情報工学部門) Copyright © 2012-2014 HASH Consulting Corp. 2
  • 3. 以下のデモは2010年のトークの 再演です(3年ちょっと前) Copyright © 2010-2014 HASH Consulting Corp. 3
  • 4. デモ1:半端な先行バイトによるXSS • 半端な先行バイトとは – Shift_JIS、EUC-JP、UTF-8などマルチバイト文字の1 バイト目だけが独立して存在する状態 – 次の文字が、マルチバイト文字の2バイト目以降の文 字として「食われる」状況になる – input要素などの引用符「”」を食わせて、イベントハ ンドラを注入する攻撃 Copyright © 2010-2014 HASH Consulting Corp. 4
  • 5. デモ1:PHPソース <?php session_start(); header('Content-Type: text/html; charset=Shift_JIS'); $p1 = @$_GET['p1']; $p2 = @$_GET['p2']; ?> <body> <form> PHP Version:<?php echo htmlspecialchars(phpversion(), ENT_NOQUOTES, 'Shift_JIS') ; ?><BR> <input name=p1 value="<?php echo htmlspecialchars($p1, ENT_QUOTES, 'Shift_JIS'); ?>"><BR> <input name=p2 value="<?php echo htmlspecialchars($p2, ENT_QUOTES, 'Shift_JIS'); ?>"><BR> <input type="submit" value="更新"> </form> </body> Copyright © 2010-2014 HASH Consulting Corp. 5
  • 6. デモ1:半端な先行バイトによるXSS 閉じる引用符が食われた状態 <input name=p1 value="・><BR> <input name=p2 value=" onmouseover=alert(document.cookie)//"><BR> ここで最初の属性値がようやく終 了 第二の属性値がイベントハンドラ に • 半端な先行バイトによるXSSが発生する条件は、 以下のいずれかを満たす場合 – htmlspecialcharsの第3引数を指定していない – PHPの5.2.11以前あるいはPHP5.3.1以前を使用 • 対策としては、以下の両方を行う – PHPの最新版を使う – htmlspecialcharsの第3引数を指定する Copyright © 2010-2014 HASH Consulting Corp. 6
  • 7. デモ2:UTF-8非最短形式によるパストラバー サル String msg = ""; String pathname = ""; try { String path = request.getParameter("path"); File f = new File(path); // パス名からファイル名を取り出す(PHPのbasename()) String filebody = f.getName(); // UTF-8としてデコード filebody = new String( filebody.getBytes("ISO-8859-1"), "UTF-8"); // ディレクトリを連結 pathname = "c:/home/data/" + filebody; // 以下ファイル読み出し FileReader fr = new FileReader(pathname); BufferedReader br = new BufferedReader(fr); ・・・ Copyright © 2010-2014 HASH Consulting Corp. 7
  • 8. • 脆弱性が発生する条件(AND条件) – Java SE6 update10以前を使用 – 文字エンコーディング変換前にファイル名をチェックしてい る Copyright © 2010-2014 HASH Consulting Corp. 8
  • 9. デモ3:5C問題によるSQLインジェクション • 5C問題とは – Shift_JIS文字の2バイト目に0x5Cが来る文字に起因する問題 ソ、表、能、欺、申、暴、十 … など出現頻度の高い文字が多 い – 0x5CがASCIIではバックスラッシュであり、ISO-8859-1など1 バイト文字と解釈された場合、日本語の1バイトがバックスラ ッシュとして取り扱われる – 一貫して1バイト文字として取り扱われれば脆弱性にならない が、 1バイト文字として取り扱われる場合と、Shift_JISとして取り 扱われる場合が混在すると脆弱性が発生する Copyright © 2010-2014 HASH Consulting Corp. 9
  • 10. ソースコード(要点のみ) <?php header('Content-Type: text/html; charset=Shift_JIS'); $key = @$_GET['name']; if (! mb_check_encoding($key, 'Shift_JIS')) { die('文字エンコーディングが不正です'); } // MySQLに接続(PDO) $dbh = new PDO('mysql:host=localhost;dbname=books', 'phpcon', 'pass1'); // Shift_JISを指定 $dbh->query("SET NAMES sjis"); // プレースホルダによるSQLインジェクション対策 $sth = $dbh->prepare("SELECT * FROM books WHERE author=?"); $sth->setFetchMode(PDO::FETCH_NUM); // バインドとクエリ実行 $sth->execute(array($key)); ?> Copyright © 2010-2014 HASH Consulting Corp. 10
  • 11. 5C問題によるSQLインジェクションの説明 Copyright © 2010-2014 HASH Consulting Corp. 11
  • 12. 5C問題によるSQLインジェクションの対策 • データベース接続時に文字エンコーディングを正しく設 定する – 文字エンコーディングを設定できるライブラリを選択する – アプリケーション上で、文字エンコーディングを設定する • PDOは、PHP5.3.7から上記ができるようになった <?php $dbh = new PDO('mysql:host=xxx;dbname=xxx;charset=utf8', USERNAME, PASSWORD); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $sth = $dbh->prepare("select * from test WHERE a=? and c=?"); $sth->bindParam(1, $a, PDO::PARAM_STR); $sth->bindParam(2, $c, PDO::PARAM_INT); $sth->execute(); Copyright © 2010-2014 HASH Consulting Corp. 12
  • 13. デモ4:UTF-7によるXSS <?php session_start(); header('Content-Type: text/html; charset=EUCJP'); $p = @$_GET['p']; if (! mb_check_encoding($p, 'EUCJP')) { die('Invalid character encoding'); } ?> <body> <?php echo htmlspecialchars($p, ENT_NOQUOTES, 'EUCJP'); ?> </body> Copyright © 2010-2014 HASH Consulting Corp. 13
  • 14. UTF-7によるXSSの説明 HTTPレスポンス EUCJPという文字エンコーディン HTTP/1.1 200 OK グをIEは認識できない(正しくは Content-Length: 187 EUC-JP) Content-Type: text/html; charset=EUCJP <body> +ADw-script+AD4-alert(document.cookie)+ADw-/script+AD4</body> IEはレスポンスの内容から、このコ ンテンツはUTF-7と判定する UTF-7として解釈されたコンテンツ <body> <script>alert(document.cookie)</script> </body> JavaScriptが 起動される Copyright © 2010-2014 HASH Consulting Corp. 14
  • 15. デモ5:U+00A5によるSQLインジェクション Class.forName("com.mysql.jdbc.Driver"); Connection con = DriverManager.getConnection( "jdbc:mysql://localhost/books?user=phpcon&passwo rd=pass1"); String sql = "SELECT * FROM books where author=?"; // プレースホルダ利用によるSQLインジェクション対策 PreparedStatement stmt = con.prepareStatement(sql); // ? の場所に値を埋め込む(バインド) stmt.setString(1, key); ResultSet rs = stmt.executeQuery(); // クエリの実行 Copyright © 2010-2014 HASH Consulting Corp. 15
  • 16. U+00A5によるSQLインジェクションの原理 IPA:安全なSQLの呼び出し方(http://www.ipa.go.jp/security/vuln/websecurity.html)より引用 16
  • 17. U+00A5によるSQLインジェクションの条件と対 策 • 脆弱性が発生する条件 – JDBCとしてMySQL Connector/J 5.1.7以前を使用 – MySQLとの接続にShift_JISあるいはEUC-JPを使用 – 静的プレースホルダを使わず、エスケープあるいは動的プレー スホルダ(クライアントサイドのバインド機構)を利用してい る • 対策(どれか一つで対策になるがすべて実施を推奨) – MySQL Connector/Jの最新版を利用する – MySQLとの接続に使用する文字エンコーディングとして Unicode(UTF-8)を指定する (接続文字列にcharacterEncoding=utf8を指定する) – 静的プレースホルダを使用する (接続文字列にuseServerPrepStmts=trueを指定する) Copyright © 2010-2014 HASH Consulting Corp. 17
  • 18. デモ6:U+00A5によるXSS // PHPでもU+00A5がバックスラッシュに変換されるパターンはないか <?php header('Content-Type: text/html; charset=Shift_JIS'); $p = @$_GET['p']; // JSエスケープ → '→' "→ " $p1 = preg_replace('/(?=['"])/u' , '', $p); $p2 = htmlspecialchars($p1, ENT_QUOTES, 'UTF-8'); ?> <html><head> <script type="text/javascript"> function foo($a) { document.getElementById("foo").innerText= $a; } </script></head> <body onload="foo('<?php echo $p2; ?>')"> p=<span id="foo"></span> [mbstring] mbstring.internal_encoding = UTF-8 </body> mbstring.http_input = auto </html> mbstring.http_output = cp932 mbstring.encoding_translation = On mbstring.detect_order = SJIS-win,UTF-8,eucJP-win Copyright © 2010-2014 HASH Consulting Corp. 18
  • 19. U+00A5によるXSSが発生する原理と条件 • 脆弱性が発生する条件 – PHP5.3.3(以降)を利用している • それより前のバージョンでは、U+00A5は全角の「¥」に変換されて いた – 以下の文字エンコーディング • 入力:自動、あるいはなんらかの経路でU+00A5の文字が入る • 内部:UTF-8 • 出力:cp932 あるいは cp51932 Copyright © 2010-2014 HASH Consulting Corp. 19
  • 20. デモ7: SQL Serverの文字集合問題 • ASP.NET + MS SQL Server + JSON • 1行掲示板 • 問題の原因はMS SQL Serverの以下のテーブル定義 CREATE TABLE chat1 ( id int IDENTITY (1, 1) NOT NULL , ctime datetime NOT NULL, body varchar (150) NOT NULL, json varchar (200) NOT NULL ) • json列にJSON形式に加工済みの投稿情報を格納して、閲 覧時には「そのまま」レスポンスとして返す • 問題はどこに? Copyright © 2010-2014 HASH Consulting Corp. 20
  • 21. 投稿スクリプト sqlUrl = "Server=labo1; database=tokumaru;user id=sa;password=xxxxx” dbcon = New SqlConnection(sqlUrl) 'DBコネクション作成 dbcon.Open() 'DB接続 sqlStr = "insert into chat1 values(sysdatetime(), @body, @json)" dbcmd = New SqlCommand(sqlStr, dbcon) body = Request("body") e_body = Regex.Replace(body, "([<>'""])", "$1") e_body = Regex.Replace(e_body, "[rn]", "") ' JSON組み立て json = "{""ctime"":""" _ & DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") _ & """, ""body"":""" & e_body & ""“}" ' パラメータ dbcmd.Parameters.Add(New SqlParameter("@body", body)) dbcmd.Parameters.Add(New SqlParameter("@json", json)) dbResult = dbcmd.ExecuteNonQuery() Copyright © 2010-2014 HASH Consulting Corp. 21
  • 22. 表示(HTML) <html><head><script src="jquery-1.4.3.min.js"></script> <script> function load() { var requester = new XMLHttpRequest(); requester.open('GET', 'json.aspx', true); requester.onreadystatechange = function() { if (requester.readyState == 4) { onloaded(requester); } }; requester.send(null); } function onloaded(requester) { res = requester.responseText; obj = eval("(" + res + ")"); $('#result').text(obj.ctime + ":" + obj.body); } </script></head><body> <input type="button" onclick="load();" value="hoge"/> <div id="result"></div></body> Copyright © 2010-2014 HASH Consulting Corp. 22
  • 23. 表示(JSON) sqlUrl = "Server=labo1; database=tokumaru;user id=sa;password=xxxx" dbcon = New SqlConnection(sqlUrl) 'DBコネクション作成 dbcon.Open() 'DB接続 sqlStr = "select top 1 * from chat1 order by id desc" dbcmd = New SqlCommand(sqlStr, dbcon) 'SQL文実行 dataRead = dbcmd.ExecuteReader() dataRead.Read() Response.AddHeader("Cache-Control", "no-cache") Response.AddHeader("Content-Type", "application/json") 'ラベルに表示 Response.write(dataRead("json")) ' エスケープ済みなのでそのまま表示 Copyright © 2010-2014 HASH Consulting Corp. 23
  • 24. 脆弱性の原因 • MS SQL Serverのvarcharは、CP932(マイクロソフト標 準キャラクタセットのShift_JIS)となる • Unicodeの列はnvarcharで宣言すること • varchar型の列にinsertする際に、Unicode→CP932の文字 エンコーディング(文字集合)の変換が発生する – U+00A5(円記号)は0x5Cに Copyright © 2010-2014 HASH Consulting Corp. 24
  • 25. 対策 • 以下のいずれかを実施すれば脆弱性は発生しない – JSONの組み立てを表示(出力)の直前に行う • DB格納前の組み立ては危険 – 英数字以外の文字は、Unicode形式でエスケープする • uNNNNの形式 • いわゆる過剰エスケープ(個人的には嫌いだがやむなし) – 文字集合の変更をしない(nvarcahr型の列を使う) – JSONの解釈にevalを使わない • jQuery使うなら、とことん使えよ • JSONPの場合は、実質evalと同じなので他の対策で… • 「いずれか」ではなく「すべて実施」を推奨 Copyright © 2010-2014 HASH Consulting Corp. 25
  • 26. 今はどうなの? Copyright © 2010-2014 HASH Consulting Corp. 26
  • 27. これまでのデモを原因別に分類すると… • 文字エンコーディングとして不正なデータによる攻撃 – デモ1:半端な先行バイトによるXSS – デモ2:UTF-8非最短形式によるパストラバーサル • 文字エンコーディングとして不正でなく、マルチバイト 文字対応が不十分なもの – デモ3:5C問題によるSQLインジェクション – デモ4:UTF-7によるXSS • 文字集合の変更が原因となるもの – デモ5:U+00A5によるSQLインジェクション – デモ6:U+00A5によるXSS – デモ7:U+00A5によるスクリプトインジェクション Copyright © 27 2010 HASH
  • 28. 対応状況まとめ Copyright © 2010-2014 HASH Consulting Corp. 28
  • 29. IE側の対応(1) IE側でも、「半端な先行バイト」によるXSS 対策が入っている。実施時期は不明。 Shift_JISとして不正な並びがある場合は、2 バイト1文字とせずに、別の文字と解釈する。 Copyright © 2010-2014 HASH Consulting Corp. 29
  • 30. IE側の対応(2) Copyright © 2010-2014 HASH Consulting Corp. 30
  • 31. UTF-7 XSSを巡る冒険 • IEの古典的なUTF-7 XSSは、MS10-090(2010年12月)にて改修され ている – 文字エンコーディング推測の変更 • ただし、MS10-090のドキュメントには明記されていない • MS10-090に含まれるIEの改修は2種類 – CVE-2010-3342とCVE-2010-3342 – どちらもキャッシュ周りの脆弱性…同じもののように見える • 以下は、はせがわようすけさんの推測(MS確認済み) – CVE-2010-3342は文字コード関連の脆弱性の修正である – CVE-2010-3348はキャッシュ周りの脆弱性の修正である – MS10-090内の記述が誤っている • script要素で文字エンコーディングを指定する攻撃方法は依然とし て有効なので注意 Copyright © 2010-2014 HASH Consulting Corp. 31
  • 32. まとめ • 文字コードに起因する脆弱性は、プラットフォーム側で の整備が進み安全性が強化されつつある • 最新のソフトウェアを使い、正しく文字エンコーディン グを設定する • アプリ側で文字エンコーディングのバリデーションをし なくても脆弱性にならないことが本来の姿 • 文字集合の問題は残る課題 – できるだけ文字集合を変更しない(Unicodeで統一) – JavaScriptなら、ユニコード・エスケープにすると安全性が高 まる。 △ " → " ○ " → u0022 Copyright © 2010-2014 HASH Consulting Corp. 32