問題4. 5. Stored XSS via AJAX
調査
4問目 5問目は「Find an XSS attack that uses a bug in Jarlsberg’s AJAX code. The attack should be triggered when you click the refresh link on the page. 」。AjaxのバグによるXSS攻撃方法を発見できるか。refreshリンクをクリックしたときに発動するようにする。
初めに、refresh処理実行時に何が行われるのかを確認する。
<div> <h2 class='has-refresh'>Jarlsberg: Home</h2> <div class='refresh'><a class='button' onclick='_refreshHome("2061610856")' href='#'>Refresh</a></div> </div>
_refreshHomeという関数が、idを引数として呼び出されるようだ。それでは、次に_refreshHomeが何をやっているか確認。
/** * Refreshes the current page by loading the url and then passing the * json response object to the callback. */ function _refresh(url, callback) { var httpRequest = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"); httpRequest.onreadystatechange = function() { if (httpRequest.readyState == 4) { _feed = callback; eval('(' + httpRequest.responseText + ')'); httpRequest = null; } } httpRequest.open("GET", url, true); httpRequest.send(null); }; /** * Processes refresh response {'private_snippet':snippet, user:snippet, ...} */ function _finishRefreshHome(response) { for (var uid in response) { var element = document.getElementById(uid); if (element) { element.innerHTML = response[uid]; } } }; function _refreshHome(uniqueId) { _refresh("/" + uniqueId + "/feed.jtl", _finishRefreshHome); };
なるほど、ajaxで”/uniqueId/feed.jtl”をGETし、レスポンスをevalしている。よって、レスポンスのJSONに実行コードを埋め込めればいい。ちなみに、ajaxのアクセス先URLにブラウザでアクセスすると、以下のようなjsonが返ってくる。
脆弱性の確認
以下のとおり、Snippetsを登録。
その後、Refreshリンクを押下すると、cookieの中身が表示される。
解決方法
JSON生成時に、シングル&ダブルクオーテーションを正しくエスケープする必要がある。具体的には、\x27または\x22にエスケープしてやればよい。また、evalの代わりに、JSON.parseのような、より安全なパーサーを使用することを、JSON in JavaScriptでは薦めている。