サイバーセキュリティ演習
― Webセキュリティ基礎&実践―
9.偽リクエストによるサービスの不正利用対策
講義内容
1. 2*. Webサイトの仕組みとWebプログラミング基礎
3.4.5*. 不正スクリプトの実行対策
6.7*.
データベースの不正操作対策
8 *.
システムの不正操作対策とHTTPレスポンスの改竄対策
9 *.
偽リクエストによるサービスの不正利用対策
10*.
セッションIDの不正取得対策
11.
総合演習(1)
12*.
公開ディレクトリの不正横断対策と認証認可制御の欠落
による不正アクセス対策とエラーメッセージからの情報
漏えい対策
13.
総合演習(2)
14.
総合演習(3)
15.
学期末試験
※*はレポートがある回になります。
本日の内容
クロスサイト・リクエスト・フォージェリ
(CSRF)の脆弱性攻撃体験と脆弱性の修正
意図しない命令の実行
不完全な対策
演習テーマ
CSRF
「意図しない命令の実行」のリンクをクリックしま
しょう。
クロスサイトリクエストフォー
ジェリ(CSRF)とは、
Cross-Site Request Forgery
サイト横断型リクエスト偽造
攻撃者が他人のWebサイトに罠のリンクを埋め込み、
偽造のリクエストを送信することで、認証済みの
ページ上でしか行えない処理を不正に実行する脆弱
性
Webの認証状態の管理方法
Cookie
6
Cookie
クライアントの端末にログインID、パスワード、認証状
態やアクセス履歴などセッション情報を一時的に保存す
る仕組み
オンラインショップにアクセス
ID yamada
PW ********
ログインページを送付
IDとパスワード入力
ユーザ専用ページを送付
セッション情報を通知
クライアント
購入ページにアクセス
次回から、ブラウ
ザはCookieに保
存したセッション
情報を送信
購入ページを送信
ログアウト
ログアウト後のページを送付
DBで管理する
ID、パスワード
を参照し認証
DB
Webサーバ
セッション情報をも
とに個人を特定
セッション情報は一
定期間保持
HTTPレスポンスの例
HTTP/1.1 200 OK
レスポンスメッセージ
Date: Thu, 24 Sep 2015 01:05:20 GMT
レスポンスヘッダ
Server: Apache/2
Cache-Control: no-cache
Expires: 0
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=shift_jis
Location: http://survey.html
Set-Cookie: ssid=123456789;path=/var/www/html/
<html>(省略)</html>
レスポンスボディ
CSRFの攻撃方法の一例
(ログインしていない場合)
8
ID yamada
PW ********
脆弱性があるオンライン
ショップWebサイト
④認証要求
DB
クライアント
②第三者のWebサーバにア
クセスした時に、罠のURLを
クリックしてしまう
Webサーバ
③クリックにより
意図しないリクエ
ストが送信される
第三者の
Webサーバ
攻撃者
①事前に、罠の
URLを張り付ける
意図しないリクエス
トが実行されない
CSRFの攻撃方法の一例
(ログイン中の場合)
9
脆弱性があるオンライン
ショップWebサイト
ログイン中
DB
クライアント
②第三者のWebサーバに
アクセスした時に、罠の
URLをクリックしてしまう
Webサーバ
③クリックにより
意図しないリクエ
ストが送信される
第三者の
Webサーバ
攻撃者
①事前に、罠の
URLを張り付ける
④意図しないリクエ
ストが実行される
パスワードの変更
公開設定の変更 など
ログインしたユーザのみが変更可能な設定を不正に操作されてしまう。
CSRFとXSSの違い
10
XSSの場合、
④レスポンスの意図しないスクリプトが実行される
不正スクリ
プト実行
(XSS)
不正操作
(CSRF)
ログイン中
クライアント
②第三者のWebサーバに
アクセスした時に、罠の
URLをクリックしてしまう
DB
Webサーバ
③クリックにより
意図しないリクエ
ストが送信される
第三者の
Webサーバ
攻撃者
①事前に、罠の
URLを張り付ける
CSRFの場合、
④意図しないリクエ
ストが実行される
演習内容(疑似的な攻撃)
掲示板に罠のリンクを張り付け、クリックによってSNS
サイトの個人情報公開設定を変更する
第三者のウェブサイト
掲示板
脆弱性がある
ウェブサイト
SNSサイト
演習の進め方
1. Webサイトの挙動を把握する
2. 脆弱性となる箇所を特定する
3. 罠のリンクを考える
4. 罠のリンクを掲示板に投稿する
5. 第三者の個人情報設定が変更されることを確認す
る。
1.Webサイトの挙動を把握
する
SNSにログイン後、設定変
更ページに移動し、個人情
報公開設定が「非公開」に
なっていることを確認する。
IDは「yamada」、パ
スーワードは
「P@ssword」
攻撃者として、利用できる
ことを考える。
設定変更ページのソースを
確認しましょう。
公開/非公開設定した後の
URLも確認しましょう。
2.脆弱性となる箇所を特定す
る
公開と非公開が指定されたパラメータを確認できま
したか?
http://localhost/Web/Scenario113/VulSoft/sns.php
?page=4&secret_token=ialeltofu7c6v63hbtuol4nid
4&name=yamada&year=1990&month=1&day=1&
mail=yamada%40example.com&public=1
public=1は公開
public=0は非公開
3.罠のリンクを考える
SNSサイトの公開設定変更時には、次のURL文が作成され
ます。
http://localhost/Web/Scenario113/VulSoft/sns.php?pag
e=4&secret_token=ialeltofu7c6v63hbtuol4nid4&name=y
amada&year=1990&month=1&day=1&mail=yamada%4
0example.com&public=1
「非公開」から「公開」に変更するURLを考えましょう。
不要なパラメータは削ってください。
secret_token, name, year, month, day, mail
http://localhost/Web/Scenario113/VulSoft/sns.php?pag
e=4&public=1
4.罠のリンクを掲示板に投稿
する
罠のリンクをURL欄に入
力し投稿しましょう。
http://localhost/We
b/Scenario113/VulS
oft/sns.php?page=
4&public=1
5.第三者の個人情報設定が変
更されることを確認する。
第三者のアカウントでログインをしましょう。
ログインIDは「sato」
パスワードは「sato310」
罠のURLをクリックすることによって、佐藤さんの
個人情報公開設定が「非公開」から「公開」になっ
てしまうことを確認しましょう。
5.第三者の個人情報設定が変
更されることを確認する。
「Congratulations!!演習の目標を達成しまし
た。」と表示されたら、OKです。
CSRFの一般的な影響
ログインユーザのみが利用可能なサービスを悪用される
ショッピングサイトなどのウェブアプリケーションへユーザが
意図しないリクエストを送信させられることで、不正送金、商
品購入、退会処理など、ユーザに不利益となる被害や、不快と
思われる行為が、ユーザの気がつかないうちに実行されてしま
う。
ログインユーザのみが編集可能な情報を改ざんされる
SNSなどのウェブアプリケーションにユーザの意図しないリク
エストを送信させられることで、各種設定の変更(管理者画面、
パスワードなど)、掲示板への不適切な書き込みなどが、ユー
ザの気がつかないうちに実行されてしまう。
対処方法
原因
ログインしたユーザからのリクエストに対して、その
ユーザが意図したリクエストであるかどうかを識別す
る仕組みを持たないために、認証状態を悪用され、不
正な操作が実行されてしまう
対処方法
罠のURLを経由したリクエストと正規のリクエストを識
別できるよう、リクエストにトークン(秘密情報)を
付加し、検証する機能を実装する。
トークンとは
第三者が知りえない秘密情報として用いる暗号
理論的に安全な疑似乱数
ユーザからリクエストを受けた際に、ログイン時
のトークンとの比較により検証する
HTMLのinputタグにhiddenパラメータとともに指
定され、ブラウザ上には表示されない
SNSサイトの設定変更ページのソースコードを確
認してみましょう。
<input type="hidden" name="secret_token"
value="ihv95674r654qgc926qfo9njk0"/>
トークン処理の流れ
GET送信とPOST送信
GET送信
URLに入力値を含めてデータを送信する
送信できるデータはテキストのみ
宣言しない場合はGETで送信される(デフォルト)
GET送信でトークンを送付すると、外部サーバのア
クセスログにトークンを含むURLが記録されてしま
い、トークンが漏れる可能性があるので注意
POST送信
URLに入力値を含めずデータを送信する
送信できるデータはテキストとバイナリが可能
トークンを含むリクエストはPOST送信で実施すべき
演習内容(脆弱性の修正)
SNSサイトのCSRFの脆弱性となるコードを特定し、
トークンをチェックし一致しない場合はログイン画面へ
遷移する実装を行う
修正プログラム
SNSサイト
sns.php
sns113.class.php
sns113.class.ph
pの処理内容を
ゲット
SNSの内容(データベースの
データ)の初期設定
メッセージ割り
当て
設定完了画面の処理
テンプレート表
示
日付チェック
攻撃成功判定
個人情報設定変更時の検証処理
SQL文の処置
生年月日、ユーザIDの取得
リファラ(参照元)チェック
ログイン状態の検証
脆弱性の修正の手順
sns113.class.php
public function validate_is_logined()
1. 処理内容の確認。
2. トークンチェック機能を追加する箇所の特定。
3. トークンチェック機能の実装。
1.処理内容の確認
public function validate_is_logined()
{
$session = $this->get_session();
$param = $this->get_param();
セッション情報とパ
ラメータ情報を取得
parent::validate_is_logined();
return $this;
}
ログイン処理を実行
2.トークンチェック機能を追
加する箇所の特定
public function validate_is_logined()
{
$session = $this->get_session();
$param = $this->get_param();
parent::validate_is_logined();
return $this;
}
3.トークンチェック機能の実
装
public function validate_is_logined()
{
$session = $this->get_session();
「ページ番号が同じ」かつ「変数が
セットされNULLではない」かつ
「トークンが異なる」場合
$param = $this->get_param();
if (($this->get_page() == parent::PAGE_SETTING) && isset($session[$this>get_login()]["secret"]) && ($session[$this->get_login()]["secret"] !==
$param["secret_token"]))
{
$this->set_session($this->get_login(), false);
$this->set_page(parent::PAGE_LOGIN);
$this->set_content(self::WARNING9, true);
return false;
} else {
ログイン処理結果を失敗に、
出力ページをログインペー
ジに、出力メッセージを警
告メッセージに設定し、
falseを返す
parent::validate_is_logined();
}
}
そうでない場合、ログイン処理を実行
動作確認
佐藤さんのアカウントでSNSにログインしましょう。
ログインIDは「sato」、パスワードは「sato310 」
掲示板のURL欄に次のURLを投稿しましょう
http://localhost/Web/Scenario113/EditSoft/sns.p
hp?page=4&public=1
「不正なリクエストです。」と出力され、佐藤さんの個
人情報公開設定が「非公開」から「公開」にならなけれ
ばOKです。
本日の内容
クロスサイト・リクエスト・フォージェリ
(CSRF)の脆弱性攻撃体験と脆弱性の修正
意図しない命令の実行
不完全な対策
演習テーマ
CSRF
「不完全な対策」のリンクをクリックしましょう。
CSRFの不完全な対策
CSRFの対策として、リクエストにトークンを含ませる方
法は有効だが、トークンに規則性がある場合、悪意のある
人に推測され、対策を回避されてしまう可能性がある
演習内容(疑似的な攻撃)
SNSサイトで利用されるトークンの規則性を発見する
脆弱性があるウェブサイト
SNSサイト
演習の進め方
1. Webサイトの挙動を把握する
2. 脆弱性となる箇所を特定する
1.Webサイトの挙動を把握
する
SNSにログイン後、設定変
更ページに移動し、設定変
更をしましょう。
IDは「yamada」、パ
スーワードは
「P@ssword」
攻撃者として、利用できる
ことを考える。
設定変更ページのソースを
確認しましょう。
2.脆弱性となる箇所を特定す
る
トークンの規則性を確認できましたか?
<input type="hidden" name="secret" value="1000"
/>
トークンは連番で割り当てられます。
ログインし直すと、secretパラメータの値がインクリ
メントされることが確認できます。
対処方法
原因
ログインしたユーザからのリクエストに対して発行す
るトークンが規則性を有するため、トークンを推測さ
れてしまい、不正な操作が実行されてしまう
対処方法
CSRFの対策として秘密情報を使用する場合は、安全な
疑似乱数を用いて、第三者に予測困難なトークンを利
用する
演習内容(脆弱性の修正)
SNSサイトのCSRFの脆弱性となるコードを特定し、安
全な擬似乱数により生成したトークンを使用する実装を
行う
修正プログラム
SNSサイト
sns.php
sns114.class.php
sns114.class.ph
pの処理内容を
ゲット
SNSの内容(データベースの
データ)の初期設定
メッセージ割り
当て
設定入力画面の処理
テンプレート表
示
個人情報設定変更時の検証処理
ログイン処理
トークン割り当ての処理
脆弱性の修正の手順
sns114.class.php
public function prepare_set_token()
1. 処理内容の確認。
2. トークンを割り当る箇所の特定。
3. 予測困難なトークン割り当ての実装。
1.処理内容の確認
public function prepare_set_token()
{
$db = $this->get_db();
$param = $this->get_param();
データベース情報、
パラメータ、セッ
ション情報を取得
$session = $this->get_session();
$token = null;
try {
$get_stmt = $db->prepare(self::GET_TOKEN_SQL);
$get_stmt->execute();
$token = $get_stmt->fetch();
} catch(Exception $e) {
トークン検索のSQL
を準備し、実行
throw new Exception((__LINE__ . json_encode($this->_db->errorInfo())),
LogUtil::ERROR_DB_EXECUTE);
}
(次ページに続く)
1.処理内容の確認
(つづき)
トークン更新のSQL
文を準備し実行
try {
$update_stmt = $db->prepare(self::UPDATE_TOKEN_SQL);
$update_stmt->execute();
} catch(Exception $e) {
throw new Exception((__LINE__ . json_encode($this->_db>errorInfo())), LogUtil::ERROR_DB_EXECUTE);
トークン割り当て
}
$session[$this->get_login()][self::TOKEN] = $token["value"];
$this->set_session($this->get_login(), $session[$this>get_login()]);
セッション情報として
return $this;
セット
}
2.トークンを割り当る箇所の
特定
(つづき)
try {
$update_stmt = $db->prepare(self::UPDATE_TOKEN_SQL);
$update_stmt->execute();
} catch(Exception $e) {
throw new Exception((__LINE__ . json_encode($this->_db>errorInfo())), LogUtil::ERROR_DB_EXECUTE);
}
$session[$this->get_login()][self::TOKEN] = $token["value"];
$this->set_session($this->get_login(), $session[$this>get_login()]);
return $this;
}
3.予測困難なトークン割り当
ての実装
(つづき)
try {
$update_stmt = $db->prepare(self::UPDATE_TOKEN_SQL);
$update_stmt->execute();
} catch(Exception $e) {
throw new Exception((__LINE__ . json_encode($this->_db>errorInfo())), LogUtil::ERROR_DB_EXECUTE);
}
$session[$this->get_login()][self::TOKEN] = session_id();
$this->set_session($this->get_login(), $session[$this>get_login()]);
今回はセッションIDで使われている
return $this;
疑似乱数をそのまま利用している。
}
(本来はNG)
動作確認
SNSにログインし、設定変更ページに移動しましょう。
ログインIDは「yamada」、パスワードは
「P@ssword 」
ソースコードを表示し、トークンが疑似乱数に変わって
いればOKです。
CSRFの要点
CSRFの脆弱性の原因は、ユーザが意図したリクエ
ストであるかどうかを識別する仕組みを持たない
ことです。
Webページを出力する際には、第三者に予測困難
なトークンをhiddenパラメータに挿入するように
しましょう。そして、ユーザからのリクエストを
受けた際には、hiddenパラメータの値と元のトー
クンを比較し、一致しない場合は処理を行わない
ようにしましょう。
課題
実際に、CSRFの脆弱性を突かれて被害を受
けた事件を調査し、1)被害の内容と時期、
2)攻撃方法とその攻撃で可能だったこと、
3)脆弱性が生まれた原因、4)実施され
た対策について、参考にした情報源などを
引用しつつ簡潔にまとめてください。
本講義の感想、要望、質問などあれば、書
いてください。
https://moodle.artsci.kyushu-u.ac.jp/course/view.php?id=2661
© Copyright 2026 ExpyDoc