不正スクリプトの実行対策(3)

サイバーセキュリティ演習
― Webセキュリティ基礎&実践―
5. 不正スクリプトの実行対策
講義内容
1. 2*. Webサイトの仕組みとWebプログラミング基礎
3.4.5*. 不正スクリプトの実行対策
6.7*.
データベースの不正操作対策
8 *.
システムの不正操作対策とHTTPレスポンスの改竄対策
9 *.
偽リクエストによるサービスの不正利用対策
10*.
セッションIDの
不正取得対策
11.
総合演習(1)
12*.
公開ディレクトリの不正横断対策と認証認可制御の欠落
による不正アクセス対策とエラーメッセージからの情報
漏えい対策
13.
総合演習(2)
14.
総合演習(3)
15.
学期末試験
※*はレポートがある回になります。
本日の内容
 クロスサイトスクリプティングの脆弱性攻
撃体験と脆弱性の修正
 ウェブページの改竄(DOMベース)
 不完全な対策
クロスサイトスクリプティング
の種類
 反射型クロスサイト・スクリプティングの脆弱性
 ウェブアプリケーションが、ユーザからの入力データに含
まれる不正なスクリプトを、そのままウェブページに埋め
込んでしまうことによって実行される。
 格納型クロスサイト・スクリプティングの脆弱性
 ウェブアプリケーション内部に不正なスクリプトを保存し
てしまうことによって、ページを閲覧するごとにスクリプ
トが実行される。
 DOMベースのクロスサイト・スクリプティングの脆
弱性
 DOM(Document Object Model)を利用しているスクリプ
トが、DOMツリーに存在する不正なスクリプトをウェブ
ページの表示に利用してしまうことによって実行される。
演習テーマ
クロスサイトスクリプティング
 「ウェブページの改ざん(DOMベース)」のリンク
をクリックしましょう。
DOM(Document Object
Model)とは
 HTML文書をクライアントサイドのスクリプトから利
用するための標準化された仕様の一つ。
 ブラウザで動作するJavaScriptは、DOMツリーを用
いてHTML文書の内容を操作(読み書き)することで、
HTML文書を構成する要素を動的に変更することがで
きる。
昔はブラウザごとに制御方法が違っていたため、
ブラウザごとに専用の JavaScript のコードを用
意する必要があった。
 制御方法を統一するために DOM という仕様が生まれ
た。
HTMLとDOMの関係
 HTMLは、「要素(HTMLタグ)」「属性」「テキス
ト」、「ドキュメント」といった部品で構成されて
いる。
 DOMは、これらの部品をノードと呼ばれる「もの
(オブジェクト)」として階層的な構造(DOMツ
リー)で識別し、スクリプト(JavaScript等)か
ら、扱いたいノードを特定し操作できるようにする
仕組みを提供する。
HTMLの例
<html>
<body>
<h1 id=“title”>アンケート
ページ</h1>
<a
id=“url“ href=“survey.html
”>クリック</a>
<div id=“deadline></div>
</body>
</html>
【表示】
アンケートページ
クリック
http://example.jp/survey.html
h属性:見出しを h1(大)-h6(小)の6段階で記述する
a属性:hrefプロパティで指定したURLを設定する
div属性:段落を作成する
DOMツリーの例
Document
要素node
html
要素node
body
要素node
要素node
要素node
h1
a
div
属性node
id=title
text node
アンケー
ト
属性node
属性node
text node
属性node
id=url
href=surve
y.html
クリック
id=deadli
ne
例えば、「survey.html」のURLを、ア
タッカーページのURLに変更したいとき
①
Document
要素node
html
要素node
【JavaScritp】
①document.
②getElementById(‘url').
③href =
“http://localhost/Web/Scenario
105/attackers_page.php”;
body
要素node
②
h1
要素node
要素node
a
div
③
属性node
text node
属性node
属性node
text node
属性node
id=title
アンケー
ト
id=url
href=surv
ey.html
クリック
id=deadli
ne
例えば、 「12月末締切」という文字列
を追加したいとき
Document
要素node
html
要素node
body
【JavaScritp】
① var text =
document.createTextNode("12
月末締切");
②
document.getElementById("de
adline").appendChild(text);
要素node
要素node
要素node
h1
a
div
②
属性node
text node
属性node
属性node
text node
属性node
text node
id=title
アンケー
ト
id=url
href=surv
ey.html
クリック
id=deadli
ne
12月末締
①切
変更後のHTMLの例
<html><head><script type="text/javascript">
window.onload=function(){
document.getElementById("url").href="http://localhost/Web/Scenario105/attackers_page.php";
var text = document.createTextNode("12月末締切");
document.getElementById("deadline").appendChild(text);}
</script></head>
<body id="body">
<h1 id="title">アンケートページ</h1>
<a id="url" href="survey.html">クリック</a>
<div id="deadline"></div>
</body></html>
http://localhost/Web/Scenari
o105/attackers_page.php
DOMベースのクロスサイトス
クリプティングの原理
 ウェブアプリケーションがユーザから受け取った入
力データを、そのままの形(実行可能な形)でウェ
ブページの出力に利用してしまう。
反射型と原理は同じ
演習内容(疑似的な攻撃)
 掲示板にウェブ検索サイトの検索結果のURLを書き換え
るスクリプトを含んだ罠のリンクを貼り付け、検索結果
のURLの変更を確認する
 第三者のウェブサイト
 掲示板
 脆弱性がある
ウェブサイト
 ウェブ検索サイト
演習の進め方
1. Webサイトの挙動を把握する
2. 脆弱性となる箇所を特定する
3. スクリプトを作成する
4. スクリプトを掲示板に投稿する
5. スクリプト投稿後の動作を確認する
1.Webサイトの挙動を把握する
 検索の入力フィールドに
様々な値を入力して動作
を確認する。
 検索後のソースから
JavaScriptの処理内容と
処理している箇所を把握
しましょう
 URLも確認してみましょ
う
検索結果について
 決められたワードと解説をランダムに出力しています。
 以下のファイルを参照してみましょう。
 C:\AppGoat01\IPATool\Scenarios\Common\Sear
ch\Lang\ja
検索後のURL
 検索後のURLに検索キーワードが代入されています。
 入力値は、以下のように投稿後のURLの末尾にある?以降
に出力され、各要素は&で連結されています。
http://localhost/Web/Scenario105/VulSoft/search.php
?keyword=abc
&submit=%E6%A4%9C%E7%B4%A2
&page=1
%E6%A4%9C%E7%B4%A2⇒検索ボタンの「検索」
1.Webサイトの挙動を把握する
 JavaScript
function get_keyword() {
var param = location.search;
param = param.replace(/\+/g, decodeURIComponent(" "));
var re = /(\?|&)keyword=([^&]*)/;
return re.exec(param)[2];
}
(続きは次ページ)
現在URLを参照しURLの”+”の箇所をス
ペースに復号化
• replace(/ 変換前文字/g, 変換後文字);
• \で+をエスケープ処理(文字実体化)
している
“keyword=“の前に?または&があり、 “keyword=“以降に
&を含まない文字列を抽出し配列として返す
1.Webサイトの挙動を把握する
 JavaScript
(つづき)
検索キーワードの文字を復号化して表示
try {
var keyword = get_keyword();
document.write(decodeURIComponent(keyword));
} catch(e) {
try {
var keyword = get_keyword();
document.write(keyword);
} catch(e) {}
}
例外的なエラーが出た場合、復号化せずに表示
2.脆弱性となる箇所を特定する
 <sの文字をそれぞれの入
力フォームに入力して投
稿してみましょう。
 クエリ文字列の表示はど
うなりますか?
3.スクリプトを作成する
 検索結果のURLを以下のURLに変更するスクリプトを
作成しましょう。
 http://localhost/Web/Scenario105/attackers_page
.php
 <script>document.getElementById(“id名”).href =“変
更URL";</script>
 ソースコードからaタグのidの付け方を確認しましょう。
 id名と変更URLを修正してください。
4.スクリプトを掲示板に投稿
する
 掲示板に投稿するURLを作成しよう。
 http://localhost/Web/Scenario105/VulSoft/search.
php?page=1&submit=1&keyword=<作成スクリプト
>
 作成したスクリプトを追記してください。
 作成したURLを掲示板のURLフォームに投稿し、動作
を確認してください。
 http://localhost/Web/Scenario105/VulSoft/search.php?
page=1&submit=1&keyword=<script>document.getEle
mentById('link0').href='http://localhost/Web/Scenario105
/attackers_page.php';</script>
5.スクリプト投稿後の動作を
確認する
 「Congratulations!!演習
の目標を達成しまし
た。」と表示されたら、
OKです。
 URLが書き換わっているこ
とも確認してください。
対処方法
 原因
 外部から入力できるパラメータをそのまま使用す
るため、 HTML上にHTMLの文法上特別な意味を持
つ特殊文字があれば、そのままHTMLの処理が実行
される
 対処方法
 特殊文字の意味を打ち消し、文字そのものとして
扱うためのエスケープ処理を行う。
JavaScriptによるエスケープ
処理
 JavaScriptには、PHPのhtmlspecialchars関数のよう
にエスケープ処理をしてくれる関数はない
 JavaScriptの場合は、DOMのappendChild関数と
createTextNode関数を利用することによって、入力さ
れたデータを文字実体として扱うことができる
 かなり手間となるが、JavaScriptにエスケープ処理をす
る関数を独自に組み込むのも一つの手である。
演習内容(脆弱性の修正)
 ウェブ検索サイトのDOSベースのクロスサイト・スク
リプティングの脆弱性となるコードを特定し、動的に生
成される文言にエスケープ処理を行う
修正の前に
 動作確認用のウェブ
検索サイトの検索後
のページのソース
コードを確認してみ
ましょう
スクリプトを実行
する段落の<div>タ
グのid
が”query_string”で
あること確認して
ください。
少しソースコードが変わっています
修正プログラム
ウェブ検索サイト
 search.php
 search.class.phpを読み込み実行
 search.jsのJavaScriptファイル指定
 メッセージ割り当て
 テンプレート表示
 search.js
 URLからキーワードの抽出
 キーワードの表示
脆弱性の修正の手順
 search.js
1. JavaScriptの内容確認。
2. キーワードを表示する箇所の特定。
3. エスケープ処理を行うプログラムの修正。
1. JavaScriptの内容確認
function get_keyword() {
var param = location.search;
param = param.replace(/\+/g, decodeURIComponent(" "));
var re = /(\?|&)keyword=([^&]*)/;
return re.exec(param)[2];
}
try {
var keyword = get_keyword();
keyword = decodeURIComponent(keyword);
document.write(keyword);
} catch(e) {}
2.キーワードを表示する箇所
の特定
function get_keyword() {
var param = location.search;
param = param.replace(/\+/g, decodeURIComponent(" "));
var re = /(\?|&)keyword=([^&]*)/;
return re.exec(param)[2];
}
try {
var keyword = get_keyword();
keyword = decodeURIComponent(keyword);
document.write(keyword);
} catch(e) {}
3.エスケープ処理を行うプロ
グラムの修正
function get_keyword() {
var param = location.search;
param = param.replace(/\+/g, decodeURIComponent(" "));
var re = /(\?|&)keyword=([^&]*)/;
return re.exec(param)[2];
}
try {
var keyword = get_keyword();
keyword = decodeURIComponent(keyword);
var text = document.createTextNode(keyword);
document.getElementById(‘query_string’).appendChild(text);
} catch(e) {}
動作確認
 スクリプトを含むURLを掲示板に投稿してみましょう。
 http://localhost/Web/Scenario105/EditSoft/search.
php?page=1&submit=1&keyword=<script>docume
nt.getElementById('link0').href='http://localhost/We
b/Scenario105/attackers_page.php';</script>
 投稿したスクリプトが実行されず、そのまま文字として
出力され、検索後のURLが変更されていなければOKで
す。
DOMベースクロスサイト・ス
クリプティングの要点
 DOMベースクロスサイト・スクリプティングの脆弱性
の原因は、JavaScriptなどのスクリプトのコードに問題
があり受け取ったデータを、エスケープ処理せずにその
まま使ってWebページを出力することです。
 JavaScriptを用いてHTMLを動的に書き換える場合は、
スクリプトが実行できないようにDOMの関数
(appendChild関数・createTextNode関数)を使用
してエスケープ処理を行ってから表示するようにしま
しょう。
演習テーマ
クロスサイトスクリプティング
 「不完全な対策」のリンクをクリックしましょう。
クロスサイトスクリプティング
の入力チェック対策の回避事例
 入力値のチェック機能が入力フォームだけを想定してい
る場合、アドレス欄などから不正なスクリプトが入力さ
れることで、チェックを回避されてしまう可能性がある。
演習内容(疑似的な攻撃)
 掲示板の内容を書き換えるスクリプトを含むURLをアド
レス欄に入力し、掲示板の表記を書き換える
 脆弱性がある
ウェブサイト
 掲示板
演習の進め方
1. Webサイトの挙動を把握する
2. スクリプトを作成する
3. スクリプトを含むURLをアドレス欄に入力する
4. ページ遷移後の動作を確認する
1.脆弱性となる箇所を特定する
 <sの文字をそれぞれの入
力フォームに入力して投
稿してみましょう。
 <sの文字をURLのそれぞ
れの入力フォームに入力
して投稿してみましょう。
 投稿後のHTMLソースも
確認しましょう。
 投稿後に<sが表示されな
い(ばれない)箇所は?
2.スクリプトを作成する
 「管理者の発言:このページでは、決して誹謗中傷な
どは行わないでください。」の内容を変更するスクリ
プトを作成しよう。
 document.getElementById(“id名”).innerHTML = “変
更内容";
“id名”の付いたタグのテキストを”変更内容”に書き換える。
 ソースから該当箇所のid名を確認しましょう。
 id名と変更内容を追記したスクリプトを作成しましょう。
3.スクリプトを含むURLをア
ドレス欄に入力する
 アドレス欄に入力するURLを作成しましょう。
 http://localhost/Web/Scenario106/VulSoft/bbs.php?na
me=1&title=1&url=&content=<作成スクリプト>
 作成したスクリプトを追記してください。
 作成したURLをアドレス欄に入力しましょう。
 http://localhost/Web/Scenario106/VulSoft/bbs.php
?name=1&title=1&url=&content=<script>document
.getElementById("warning").innerHTML="管理者の発
言:このページでは誹謗中傷を歓迎します。";</script>
4.ページ遷移後の動作を確認
する
 「Congratulations!!演習の目標を達成しました。」
とアラートが表示されたら、OKです。
対処方法
 原因
 外部から入力できるパラメータをそのまま使用す
るため、 HTML上にHTMLの文法上特別な意味を持
つ特殊文字があれば、そのままHTMLの処理が実行
される
 対処方法
 特殊文字の意味を打ち消し、文字そのものとして
扱うためのエスケープ処理を行う。
修正プログラム
 掲示板
 bbs.php
メッセージ割り当て
テンプレート表示
 bbs.class.php
掲示板投稿内容の初期設定
データベース情報を表示形式に変換
演習課題の成功判定に関する処理
 bbs.js
投稿ボタン押下時の処理
タグ文字のチェック
削除ボタン押下時の処理
脆弱性の修正の手順
 bbs.class.php
1. データベースのデータ表示形式変換処理の内容の確認。
2. htmlspecialchars関数を使用する箇所の特定。
3. htmlspecialchars関数を使用したプログラムへの修正。
1.データベースのデータ表示
形式変換処理の内容の確認
public function get_contents()
{
$this->_contents["contents"] = array();
while($row = $this->stmt->fetch())
{
$content = array();
foreach($row as $k => $v)
{
$value = null;
「掲示板に埋め込まれるスクリプト(格納
型)」テーマの「脆弱性の修正」リンクに
あるbbs.cloass.phpファイルの
get_contents()関数と同じです。
詳細は、格納型XSSの第4回講義資料を参照
してください。
if ($k == parent::CONTENT) {
$value = nl2br($row[$k]);
$this->is_success($value);
} else {
$value = htmlspecialchars($row[$k], ENT_QUOTES, "UTF-8");
}
$content[$k] = $value;
}
$this->_contents["contents"][] = $content;
}
$this->_contents["token"] = AppGoatUtil::getToken();
return $this->_contents;
}
2.htmlspecialchars関数を
使用する箇所の特定
foreach($row as $k => $v) {
$value = null;
if ($k == parent::CONTENT) {
$value = nl2br($row[$k]);
$this->is_success($value);
} else {
$value = htmlspecialchars($row[$k], ENT_QUOTES,
"UTF-8");
}
$content[$k] = $value;
}
3.htmlspecialchars関数を
使用したプログラムへの修正
foreach($row as $k => $v) {
$value = null;
if ($k == parent::CONTENT) {
$value = nl2br(htmlspecialchars($row[$k],
ENT_QUOTES, "UTF-8"));
$this->is_success($value);
} else {
$value = htmlspecialchars($row[$k], ENT_QUOTES,
"UTF-8");
}
$content[$k] = $value;
}
動作確認
 スクリプトを含むURLをアドレス欄に入力してみましょ
う。
http://localhost/Web/Scenario106/Editsoft/bbs.p
hp?name=1&title=1&url=&content=<script>docu
ment.getElementById("warning").innerHTML="管理
者の発言:このページでは誹謗中傷を歓迎します。
";</script>
 入力したスクリプトが実行されなければOKです。
クロスサイト・スクリプティン
グのまとめ
 間接的攻撃の反射型、直接的攻撃の格納型のクロスサイ
ト・スクリプティングがあり、罠のリンクに誘導しスク
リプトを実行させる、あるいは入力欄やURL欄に直接ス
クリプトを投稿するなど攻撃方法は多様です。
 しかしながら、クロスサイトスクリプティングの原因は
いずれも同じで、受け取った入力値を、エスケープ処理
せずにそのまま使ってWebページに出力することです。
 外部の入力パラメータを使って出力内容が動的に生成さ
れる場合は、スクリプトが実行できないようにエスケー
プ処理をして表示するようにしましょう。
課題
 実際に、クロスサイトスクリプティングの
脆弱性を突かれて被害を受けた事件を調査
し、1)被害の内容と時期、2)攻撃方法
とその攻撃で可能だったこと、3)脆弱性
が生まれた原因、4)実施された対策につ
いて、参考にした情報源などを引用しつつ
簡潔にまとめてください。
 本講義の感想、要望、質問などあれば、書
いてください。
https://moodle.artsci.kyushu-u.ac.jp/course/view.php?id=2661