Japan Computer Emergency Response Team Coordination Center 電子署名者 Japan Computer Emergency Response Team Coordination Center DN c=jp, st=tokyo, l=chiyoda-ku, email=office@jpcert.or.jp, o=japan Computer Emergency Response Team Coordination Center, cn=japan Computer Emergency Response Team Coordination Center 日付 2013.09.27 091014 +09'00' Javaアプリケーション脆弱性事例調査資料 について この資料は Javaプログラマである皆様に 脆弱性を身 近な問題として感じてもらい セキュアコーディングの 重要性を認識していただくことを目指して作成していま す Javaセキュアコーディングスタンダード CERT/Oracle版 と合わせて セキュアコーディングに 関する理解を深めるためにご利用ください JPCERTコーディネーションセンター セキュアコーディングプロジェクト secure-coding@jpcert.or.jp 1
Blojsom におけるクロスサイト スクリプティングの 脆 弱 性 CVE-2006-4829 JVNDB-2006-001260 2
Blojsomとは BlojsomはJavaで 書 かれたブログシステム AppleのMac OS X Server 10.4 TigerのWeblog Serverは blojsomがベースとなっている 3
脆 弱 性 の 概 要 Blojsom は 入 力 された 文 字 列 の 処 理 に 不 備 があり クロスサイトスクリプティング 攻 撃 が 可 能 攻 撃 者 の 用 意 したリンクをクリックするだけでク ロスサイトスクリプティング 攻 撃 が 成 立 する クロスサイトスクリプティングにより アカウン ト 乗 っ 取 り 等 の 被 害 が 発 生 する 4
クロスサイトスクリプティングとは クロスサイトスクリプティングとは ユーザの 入 力 値 を 元 にHTMLやURLなどを 動 的 に 生 成 し ているWebサイトにおいて 攻 撃 者 によって ユーザのブラウザに 表 示 されるコンテンツに 任 意 のHTMLやJavaScriptを 埋 め 込 む 攻 撃 クロスサイトスクリプティングにより 下 記 のよ うな 被 害 が 発 生 する 不 正 なサイトへの 誘 導 Cookieの 搾 取 によるセッションの 乗 っ 取 り 不 正 プログラムの 埋 め 込 み 実 行 機 密 情 報 の 漏 えい(HTTPSページの 情 報 搾 取 や HTMLフォームの 偽 装 等 ) 5
クロスサイトスクリプティング 攻 撃 例 1ユーザーを 攻 撃 者 のWebサイトに 誘 導 2 攻 撃 者 のWebサイトにアクセス 攻 撃 者 3 攻 撃 コードを 含 むレスポンス ユーザ 攻 撃 の 流 れ 1 攻 撃 者 はユーザーを 攻 撃 者 のWebサイトに 誘 導 する 2 ユーザーは 攻 撃 者 のサイトにアクセスする 3 攻 撃 者 のサイトから 攻 撃 対 象 サイトに 対 する 攻 撃 コードを 含 むレスポンスが 返 される 4 ユーザーは 攻 撃 対 象 サイトに 対 して 攻 撃 コード を 含 むリクエストを 送 信 する 5 ユーザーは 攻 撃 コードを 含 むレスポンスを 受 信 し 攻 撃 対 象 サイトのページ 上 で 攻 撃 コードが 実 行 される 攻 撃 実 行!! 5 攻 撃 コードを 含 むレスポンス 4 攻 撃 コードを 含 むリクエスト 攻 撃 対 象 サイト 6
クロスサイトスクリプティング 攻 撃 例 6セッションIDが 奪 われる 攻 撃 実 行!! 攻 撃 者 7ユーザーになりすまし ユーザ 8 機 密 情 報 の 漏 えい 攻 撃 の 流 れ 攻 撃 対 象 サイト 6 攻 撃 コードが 実 行 され セッションIDが 奪 われる 7 攻 撃 者 は 奪 ったセッションIDを 利 用 して ユーザーになりすまして 攻 撃 対 象 サイトにアクセスする 8 攻 撃 対 象 サイト 上 のユーザー 情 報 を 奪 うことが 可 能 となる 7
Blojsom の 処 理 内 容 ブログに 新 しい 書 き 込 みを 実 施 した 場 合 の 処 理 フロー 1 クライアントのブラウザからリクエストが 送 信 され アプリケーションが 受 信 する 2 リクエストからパラメータを 取 り 出 し 処 理 (ブログの 書 き 込 み)を 実 施 3 アプリケーションは 書 き 込 み 結 果 とともに 書 き 込 み 内 容 をクライアントに レスポンスとして 送 信 し クライアントのブラウザに 表 示 される 1 3 2 8 8
Blojsomの 処 理 1クライアントからリクエストを 受 信 する クライアントから 送 信 されるリクエストは 下 記 のようになる ここではパラメータ rss-enclosure-url に 注 目 する HTTPリクエスト POST /blojsom/blog/default/ HTTP/1.1 Host 192.168.xxx.xxx Content-Length 370 ここではパラメータ rss-enclosure-url の 値 は test action=add-blog-entry&flavor=.&rss-enclosure-url=test& &submit=add+blog+entry 上 記 HTTPリクエストを 送 信 するためのHTML <form action= /blojsom/blog/default/ method= POST > <input type= text name= rss-enclosure-url value= test > <input type= submit name= post value= Add blog entry > </form> 9
Blojsomの 処 理 1クライアントからリクエストを 受 信 する ブログ 書 き 込 み 画 面 パラメータ rss-enclosure-url の 入 力 フォーム 10
Blojsomの 処 理 2リクエストの 処 理 とブログへの 書 き 込 み 処 理 リクエストからパラメータ rss-enclosure-url の 値 を 変 数 rssenclosureurl に 格 納 し ブログへの 書 き 込 み 処 理 を 実 施 する RSSEnclosurePlugin.java public class RSSEnclosurePlugin implements BlojsomPlugin, BlojsomListener { public static final String RSS_ENCLOSURE_URL = "rss-enclosure-url"; public void processevent(blojsomevent event) { ProcessBlogEntryEvent processblogentryevent = (ProcessBlogEntryEvent) event; //リクエストからパラメータrss-enclosure-urlの 値 を 取 り 出 す String rssenclosureurl = BlojsomUtils.getRequestValue(RSS_ENCLOSURE_URL, processblogentryevent.gethttpservletrequest()); (ブログへの 書 き 込 み 処 理 ) 11
Blojsomの 処 理 3 処 理 結 果 をクライアントへ 返 す 書 き 込 み 処 理 を 実 施 後 変 数 rssenclosureurlの 値 をレスポンスとしてクライ アントに 返 す RSSEnclosurePlugin.java public class RSSEnclosurePlugin implements BlojsomPlugin, BlojsomListener { public void processevent(blojsomevent event) { //クライアントに 値 を 返 す processblogentryevent.getcontext().put(rss_enclosure_url_item, rssenclosureurl); 12
Blojsomの 処 理 3 処 理 結 果 をクライアントへ 返 す アプリケーションからクライアントへ 送 信 されるHTTPレスポンスは 下 記 のよう な 内 容 になる HTTPレスポンス HTTP/1.1 200 OK Server Apache-Coyote/1.1 Pragma no-cache Content-Type text/html;charset=utf-8 Date Fri, 05 Oct 2012 072917 GMT Content-Length 26881 <html> <head> <tr> <td>url to enclosure</td> <td><input type="text" name="rss-enclosure-url" value="test" size="60" /></td> </tr> 13
Blojsomの 処 理 3 処 理 結 果 をクライアントへ 返 す 処 理 完 了 画 面 書 き 込 み 完 了 の 結 果 を 表 示 POSTした 内 容 がそのまま 表 示 される 14
攻 撃 コード 攻 撃 コードのHTTPリクエスト POST /blojsom/blog/default/ HTTP/1.1 Host 192.168.xxx.xxx Content-Length 370 action=add-blog-entry&flavor=.& rss-enclosure-url="><script>alert(123)</script>& &submit=add+blog+entry 攻 撃 コードのポイント パラメータ rss-enclosure-url にスクリプトタグを 含 む 値 を 送 信 する 15
攻 撃 コード 攻 撃 コードのHTTPリクエストを 送 信 するためのHTML <form action= /blojsom/blog/default/ method= POST > <input type= hidden name= rss-enclosure-url value= "><script>alert(123)</script> > <input type= submit name= post value= Add blog entry > </form> 被 害 者 にこのフォームのリクエストを 送 信 させることでクロスサイトスクリ プティング 攻 撃 が 成 立 する 魅 惑 のコンテンツ Click me!! 16
攻 撃 コードが 実 行 された 際 の 処 理 ブログに 新 しい 書 き 込 みを 実 施 した 場 合 の 処 理 フロー 1 クライアントのブラウザからリクエストが 送 信 され アプリケーションが 受 信 する 2 リクエストからパラメータを 取 り 出 し 処 理 (ブログの 書 き 込 み)を 実 施 3 アプリケーションは 書 き 込 み 結 果 とともに 書 き 込 み 内 容 をクライアントに レスポンスとして 送 信 し クライアントのブラウザに 表 示 される 攻 撃 が 実 施 された 際 の 処 理 フローは 正 常 な 処 理 とまったく 変 わらない 3のアプリケーションから 送 信 されるレスポンス 内 容 に 注 目 する 17
攻 撃 コードが 実 行 された 際 の 処 理 アプリケーションからクライアントに 返 されるHTTPレスポンス HTTPレスポンス HTTP/1.1 200 OK Server Apache-Coyote/1.1 <html> <head> <tr> <td>url to enclosure</td> <td><input type="text" name="rss-enclosure-url" value=""><script>alert(123)</script> size="60" /></td> </tr> <td>url to enclosure</td> <td><input type="text" name="rss-enclosure-url" value= test size="60" /></td> </tr> 挿 入 された 文 字 列 により input タグが 閉 じられ script タグが 挿 入 された 形 になる そのため ブラウザは script タグ 内 の Javascript を 実 行 してしまう 通 常 の 処 理 の 際 のレスポンス 18
問 題 点 今 回 のアプリケーションにおける 具 体 的 な 問 題 点 HTMLへ 出 力 する 際 に Javascriptとして 解 釈 される 文 字 列 を 無 害 化 していないために 脆 弱 性 が 発 生 している 以 下 のコーティングガイドに 違 反 している IDS00-J. 信 頼 境 界 を 越 えて 渡 される 信 頼 できない データは 無 害 化 する 上 記 の 問 題 点 に 対 してどうすべきだったか Javascriptとして 解 釈 される 文 字 列 を 無 害 化 してから HTMLに 出 力 すべきであった 19
修 正 版 コード 本 脆 弱 性 はバージョン2.32で 修 正 されている ブログに 新 しい 書 き 込 みを 実 施 した 場 合 の 処 理 フロー 1 クライアントのブラウザからリクエストが 送 信 され アプリケーションが 受 信 する 2 リクエストからパラメータを 取 り 出 し 処 理 (ブログの 書 き 込 み)を 実 施 3 アプリケーションは 書 き 込 み 結 果 とともに 書 き 込 み 内 容 をクライアントに レスポンスとして 送 信 し クライアントのブラウザに 表 示 される この 処 理 のコードに 修 正 が 入 っている 20
修 正 版 コード RSSEnclosurePlugin.java( 修 正 前 ) public class RSSEnclosurePlugin implements BlojsomPlugin, BlojsomListener { public void processevent(blojsomevent event) { processblogentryevent.getcontext().put(rss_enclosure_url_item, rssenclosureurl); クライアントに 値 を 返 す 際 BlojsomUtilsクラスの escapebracketsメソッドを RSSEnclosurePlugin.java( 修 正 後 ) 呼 び 出 している public class RSSEnclosurePlugin implements BlojsomPlugin, BlojsomListener { public void processevent(blojsomevent event) { processblogentryevent.getcontext().put(rss_enclosure_url_item, BlojsomUtils.escapeBrackets(rssEnclosureURL)); 21
修 正 版 コード BlojsomUtilsクラスのescapeBracketsメソッド public static String escapebrackets(string input) { if (input == null) { return null; } String unescaped = replace(input, "<", "<"); unescaped = replace(unescaped, ">", ">"); } return unescaped; 無 害 化 処 理 として 引 数 inputの 値 に 含 まれる 値 をエスケープ 処 理 している エスケープ 対 象 文 字 列 エスケープ 処 理 後 文 字 列 < < > > 22
修 正 版 コード 修 正 版 コードに 対 して 先 ほどの 攻 撃 コードを 実 行 すると 下 記 のようなHTTP レスポンスになり スクリプトが 実 行 されなくなる HTTPレスポンス HTTP/1.1 200 OK Server Apache-Coyote/1.1 <html> <head> <tr> <td>url to enclosure</td> <td><input type="text" name="rss-enclosure-url" value=""><script>alert(123)</script> size="60" /></td> </tr> エスケープ 処 理 により スクリプトが 実 行 されなくなる 23
実 はこの 修 正 では 不 十 分!! クロスサイトスクリプティングに 対 する 無 害 化 を 行 う 際 に 前 述 の 処 理 だけでは 完 全 に 無 害 化 できないケースが 存 在 する 具 体 的 にはHTMLのタグ 内 への 文 字 列 の 出 力 パラメータrss-enclosure-urlに onfocus= javascriptalert(1) という 値 を 挿 入 するこ とで 入 力 フォームにマウスカーソルを 持 っていくと Javascriptが 動 作 する パラメータrss-enclosure-urlに " onfocus="javascriptalert(1) を 挿 入 した 際 のHTTPレスポンス <td>url to enclosure</td> <td> <input type= text name= rss-enclosure-url value= " onfocus="javascriptalert(1) size="60" /></td> </tr> BlojsomUtilsクラスのescapeBracketsメソッドによる エスケープ 処 理 をバイパスできてしまう 24
さらに 修 正 次 の5 種 類 の 文 字 をHTMLエンコードする エスケープ 対 象 文 字 列 エスケープ 処 理 後 文 字 列 < < > > & & " ' さらにユーザからの 入 力 値 をタグの 属 性 値 に 埋 め 込 む 場 合 は 値 全 体 を (ダブルクオート) 文 字 で 括 る それにより a onmouseover= alert(1); という 文 字 列 を 挿 入 さ せられた 場 合 でも 次 のようなHTMLが 生 成 されるためJavaScript は 実 行 されない <input type="text" value="a" onmouseover="alert(1);"> 25
さらに 修 正 前 述 を 踏 まえてescapeBracketsメソッドを 修 正 すると 下 記 のようになる BlojsomUtilsクラスのescapeBracketsメソッド( 追 加 修 正 版 ) public static String escapebrackets(string input) { if (input == null) { return null; } String unescaped = replace(input, "<", "<"); unescaped = replace(unescaped, ">", ">"); unescaped = replace(unescaped, " & ", "&"); unescaped = replace(unescaped, " " ", """); unescaped = replace(unescaped, " ", "'"); } return unescaped; 追 加 されたコード 3つの 特 殊 記 号 に 対 する エスケープ 処 理 を 追 記 する 26
まとめ この 脆 弱 性 から 学 べるプログラミングの 注 意 点 アプリケーションの 外 部 にデータを 出 力 する 場 合 出 力 先 でデータがどのように 使 用 されるかを 考 慮 すべきだっ た 上 記 への 対 策 データの 出 力 先 がWebブラウザの 場 合 想 定 外 の 個 所 に HTML のメタ 文 字 が 含 まれている 場 合 に 備 えてHTMLエン コーディングを 施 す 参 考 OWASP XSS Filter Evasion Cheat Sheet https//www.owasp.org/index.php/xss_filter_evasion_cheat_sheet XSS (Cross Site Scripting) Prevention Cheat Sheet https//www.owasp.org/index.php/xss_(cross_site_scripting)_prevention_cheat_sheet 27
著 作 権 引 用 や 二 次 利 用 について 本 資 料 の 著 作 権 はJPCERT/CCに 帰 属 します 本 資 料 あるいはその 一 部 を 引 用 転 載 再 配 布 する 際 は 引 用 元 名 資 料 名 および URL の 明 示 をお 願 いします 記 載 例 引 用 元 一 般 社 団 法 人 JPCERTコーディネーションセンター Java アプリケーション 脆 弱 性 事 例 解 説 資 料 Blojsom におけるクロスサイトスクリプティングの 脆 弱 性 https//www.jpcert.or.jp/securecoding/2012/no.03_blojsom.pdf 本 資 料 を 引 用 転 載 再 配 布 をする 際 は 引 用 先 文 書 時 期 内 容 等 の 情 報 を JPCERT コーディ ネーションセンター 広 報 (office@jpcert.or.jp)までメールにてお 知 らせください なお この 連 絡 に より 取 得 した 個 人 情 報 は 別 途 定 めるJPCERT コーディネーションセンターの プライバシーポリ シー に 則 って 取 り 扱 います 本 資 料 の 利 用 方 法 等 に 関 するお 問 い 合 わせ JPCERTコーディネーションセンター 広 報 担 当 E-mailoffice@jpcert.or.jp 本 資 料 の 技 術 的 な 内 容 に 関 するお 問 い 合 わせ JPCERTコーディネーションセンター セキュアコーディング 担 当 E-mailsecure-coding@jpcert.or.jp 28