Webセキュリティの基本のキ

EG セキュアソリューションズ株式会社
取締役CTO 徳丸 浩
徳丸浩のウェブセキュリティ講座

アジェンダ• セッション管理• 認可制御不備• CSRF• クロスサイトスクリプティング• SQLインジェクション

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

2徳丸浩の自己紹介• 経歴– 1985年 京セラ株式会社入社– 1995年 京セラコミュニケーションシステム株式会社(KCCS)に出向・転籍– 2008年 KCCS退職、HASHコンサルティング株式会社(現社名:EGセキュアソリューションズ株式会社)設立• 経験したこと– 京セラ入社当時はCAD、計算幾何学、数値シミュレーションなどを担当– その後、企業向けパッケージソフトの企画・開発・事業化を担当– 1999年から、携帯電話向けインフラ、プラットフォームの企画・開発を担当
Webアプリケーションのセキュリティ問題に直面、研究、社内展開、寄稿などを開始– 2004年にKCCS社内ベンチャーとしてWebアプリケーションセキュリティ事業を立ち上げ• 現在––––

EGセキュアソリューションズ株式会社取締役CTO
https://www.eg-secure.co.jp/
独立行政法人情報処理推進機構 非常勤研究員https://www.ipa.go.jp/security/
著書「体系的に学ぶ 安全なWebアプリケーションの作り方（第2版）」(2018年6月)
YouTubeチャンネル「徳丸浩のウェブセキュリティ講座」
https://j.mp/web-sec-study– 技術士（情報工学部門）
徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

3セッション管理徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

4ログイン処理の様子
サーバー

利用者

example.jp
example.jp
ログイン
ユーザID
パスワード

GET /loginform HTTP/1.1

tanaka*****ログイン

example.jp

HTTP/1.1 200 OK
POST /login HTTP/1.1
id=tanaka&pass=x5831

ログイン成功しました

HTTP/1.1 200 OK
Content-Length: 43

ID、パスワードの確認<body>ログイン成功しました</body>
徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

5ログイン結果の状態をどう保存するか• ウェブが使用するプロトコルHTTPは「状態」を保存しない• ログイン結果を以降のページにも保存したい• ブラウザには「状態」を保存する機能が2種類ある– Cookie: 伝統的な方法• Set-Cookie レスポンスヘッダ：Cookieの保存をブラウザに命令
Set-Cookie: name=yamada• Cookie リクエストヘッダ：保存したCookieを自動的にサーバーに送信
Cookie: name=yamada– ウェブストレージ（ localStorage等）：JavaScriptから利用できる• setItemメソッド：localStorageへの保存
localStorage.setItem('name', 'yamada')• getItemメソッド：localStorageからの値取り出し
const name = localStorage.getItem('name') // nameには'yamada'が入る

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

6ログイン後CookieにユーザIDを保存（脆弱な処理）
サーバー

利用者

example.jp

example.jp
ログイン成功しました
マイページ

user=tanaka

POST /login HTTP/1.1

id=tanaka&pass=x5831

ID、パスワードの確認

HTTP/1.1 200 OK
Set-Cookie: user=tanaka…

ユーザIDをCookieとしてセット

マイページ

GET /mypage HTTP/1.1
Cookie: user=tanaka

ID: tanaka
メール: tanaka@example.jp
住所: 東京都港区…

HTTP/1.1 200 OK

example.jp

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

Cookieを元に個人情報を表示

7

実は、これだと問題が…

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

8機密情報のCookieへの直接保存(CWE-315)
サーバー

ハッカー

example.jp
ブラウザのCookieに
user=tanakaを設定
user=tanaka
マイページ

GET /mypage HTTP/1.1
Cookie: user=tanaka

ID: tanaka
メール: tanaka@example.jp
住所: 東京都港区…

HTTP/1.1 200 OK

example.jp

Cookieを元に個人情報を表示

容易に第三者になりすませる
CWE-315
徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

9セッション管理機能を使いましょう
利用者

サーバー

example.jp

example.jp
ログイン成功しました
マイページ

sessid=j6qkx…

POST /login HTTP/1.1

id=tanaka&pass=x5831
HTTP/1.1 200 OK
Set-Cookie: sessid=j6qkx…
…

マイページ

GET /mypage HTTP/1.1
Cookie: sessid=j6qkx…

ID: tanaka
メール: tanaka@example.jp
住所: 東京都港区…

HTTP/1.1 200 OK

example.jp

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

セッション
sessiduserid

hkzi4…

watanabe

w2zm...

yamadaJ6qkx…

tanaka

ログイン状態をセッションに保存
ID、パスワードの確認

セッションを元に個人情報を表示

10

SPAと攻撃経路

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

11

SPAの構造TOKEN orSESSION ID

Front EndStore

{ … } JSONAPI

{ … } JSON

ビジネスロジック

表示ロジックDB

localStorage

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

SessionStorage
12

SPAのセッション管理方式 1 セッションID方式
POST /login{"id":"bob","pass":"123456"}

SESSID=f8d92b0…

API

Front EndSESSID=f8d92b0…

Store

ビジネスロジック{"email":"bob@example.jp"}

表示ロジックDBSESSID=f8d92b0…

5:bob,bob@example.jp

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

SessionStorage
f8d92b0…:5,bob
13

SPAのセッション管理方式 2 ステートレストークン(JWT等)
POST /login{"id":"bob","pass":"123456"}

token=eyJhbG…

API

Front EndStore

token=eyJhbG…

ビジネスロジック{"email":"bob@example.jp"}

表示ロジック

デコード&検証{"sub":"5","exp":17…}

localStorage

5:bob,bob@example.jp

DBtoken=eyJhbG…

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

14クライアント側のロジックやデータは取得・変更可能
TOKEN orSESSION ID

Front EndStore
表示ロジック{ … }ビジネスロジック

JSON

DB

localStorage

徳丸浩のウェブセキュリティ講座

API

取得・変更

© 2023 Hiroshi Tokumaru

SessionStorage
15

JavaScriptによる検証はバイパスできる

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

16悪用例1: クライアント側バリデーションの回避
START

HTMLやJavaScritによるチェック<input type="number" min="0" max="100">※ 0～100の数値のみ許容

HTMLやJavaScriptによるチェック（バリデーション等）は攻撃者は回避可能

No

OK?
Yes
処理実行(API)

エラー

END

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

17

悪用例2: クライアントによるチェック処理の回避
START

APIによる権限チェック

No

OK?
Yes
処理実行(API)エラー

APIによる処理でも、チェックと実行（更新等）が別だと、チェック処理は回避可
能END

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

18パスワード変更機能の場合

example.jp
パスワード変更
旧パスワード新パスワード新パスワード（確認）

*****
*****
*****
変更

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

現在パスワードの確認

確認用の再入力

19パスワード変更機能の脆弱な再認証の実装
利用者
www.example.com

POST /auth HTTP/1.1{"currentPass":"P@assword"}
example.jp// 再認証に成功したら// パスワードを変更する
if (authCheck()) {changePassword()} else {error("Auth Error")}

HTTP/1.1 200 OK

POST /changepassword HTTP/1.1{"newPass":"p@ssw0rd"}
HTTP/1.1 200 OK

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

パスワード変更20パスワード変更機能の脆弱な再認証の実装
攻撃者

利用者
www.example.com

XSS攻撃

POST /auth HTTP/1.1{"currentPass":"P@assword"}
example.jp// 再認証に成功したら// パスワードを変更する
if (authCheck()) {changePassword()} else {error("Auth Error")}

HTTP/1.1 200 OK

POST /changepassword HTTP/1.1{"newPass":"cracked"}
HTTP/1.1 200 OK

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

パスワード変更

21

認可制御不備

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

22認可制御とは• 認証(Authentication): ユーザーが誰かを確認すること• 認可(Authorization): 認証されたユーザーに対して許可（権限）を与えること• アクセス制御(Access Control): 認証しているユーザーのみにアクセスを許可すること注) アクセス制御は、IPアドレス等による制御を含む場合もある

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

23認可制御不備の典型的パターン(1)http://example.jp/login

http://example.jp/logindone

ログインしましたID
パスワード
ログイン

秘密情報をどうぞ

情報リソースのURLを知っていると認証なしで情報が閲覧できる

徳丸浩のウェブセキュリティ講座

http://example.jp/secret
秘密情報・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・

URL を知っていると未ログインでも閲覧可能© 2023 Hiroshi Tokumaru

24認可制御不備の典型的パターン(2)ID:yamadaでログイン
ユーザ情報

http://example.jp/profile.php?id=100246
ようこそ yamadaさんユーザID:yamada
メールアドレス:xx
氏名: 山田〇〇電話: 03-xxxx-xxxx

情報リソースのIDを変更すると権限外の情報が参照できる

http://example.jp/profile.php?id=100247
ようこそ yamadaさん
ユーザID:sato
メールアドレス:xx
氏名: 佐藤△△電話: 06-xxxx-xxxx

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

内部ID

外部ID

100246

yamada100247sato※アプリケーション内部では表示用の外部IDではな
く、内部ID(一連番号)で管理されている

25

認可制御不備の典型的パターン(3)正常系

一般向けメニューhttp://example.jp/a001

管理者としてログイン
http://example.jp/menu

投稿閲覧
プロフィール

攻撃

一般ユーザとしてログイン
http://example.jp/menu
一般機能

一般機能
管理者機能

管理者用メニューhttp://example.jp/b001
ユーザ登録
アカウント停止
ロック解除
問い合わせ対応

URLを直接指定すると管理者用メニューが表示され実行もできる

一般向けメニューhttp://example.jp/a001
投稿
閲覧
プロフィール

管理者用メニューhttp://example.jp/b001
ユーザ登録
アカウント停止
ロック解除
問い合わせ対応

URL
書き換え

メニューの表示・非表示のみで制御している
徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

26認可制御不備の典型的パターン(4)正常系

攻撃

一般ユーザとしてログイン
Cookie: USER=normal

投稿
閲覧

投稿
閲覧
ユーザ登録
アカウント停止

管理者としてログイン
Cookie: USER=admin

一般ユーザとしてログイン
Cookie: USER=admin

投稿
閲覧
ユーザ登録
アカウント停止

Cookieに保持した権限情報を変更しただけで管理者メニューが表示され、実行もできる

hiddenパラメータやクッキーに権限情報を保持している
徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

27認可制御の正しい実装• 認可制御の基本は、以下の直前に権限を確認すること– 秘密情報の表示– 権限の必要な機能実行– その他、権限を必要とする操作• 権限を確認する基準は、セッション変数に保存したログインID• admin等の特権専用ユーザーは作らず、個人IDに権限を割り当てる仕様が好ましい• 複雑な認可制御が必要な場合は、役割を抽象化したロールを定義する• 時間経過に伴い、権限やロールが変化する場合もあるので、権限やロールはセッション変数に保存せず、都度確認する• ロールと権限を「権限マトリックス」としてドキュメント化する
徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

28ロールと権限マトリックスの例

ロール

権限

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

29

1.クロスサイト・リクエストフォージェリ(CSRF)

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

30クロスサイト・リクエストフォージェリ(CSRF)とは徳丸浩のウェブセキュリティ講座

https://www.ipa.go.jp/security/vuln/websecurity.html より引用

© 2023 Hiroshi Tokumaru

31クロスサイト・リクエストフォージェリの原理
正常系のHTTPリクエスト
POST /45/45-003.php HTTP/1.1
Referer: http://example.jp/45/45-002.php
Content-Type: application/x-www-form-urlencoded
Host: example.jp
Cookie: PHPSESSID=isdv0mecsobejf2oalnuf0r1l2
Content-Length: 9
pwd=pass1

CSRF攻撃時のHTTPリクエスト
POST /45/45-003.php HTTP/1.1
Referer: http://trap.example.com/45/45-900.html
Content-Type: application/x-www-form-urlencoded
Host: example.jp
Cookie: PHPSESSID=isdv0mecsobejf2oalnuf0r1l2
Content-Length: 9

Referer
以外は変わらない

pwd=pass1
徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

32クロスサイト・リクエストフォージェリの影響と対策• 影響– 脆弱性のある機能を第三者に強制される– パスワード変更– 勝手な投稿、変更、削除– 物品購入• 対策– 方法1 トークン(Token)による方法（推奨）※ アプリケーションフレームワークのCSRF対策機能を素直に使う– 方法2 パスワード確認（再認証）– 保険的対策：重要な処理実行後に登録済みメールアドレスに通知を送付する

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

33

補足：CookieのSameSite属性について• SameSite属性は、異なるサイトから遷移した場合に、クッキーを送信するかどうかを制御するもの
元々Cookieがセットされていた場合に、Cookieが送信されるかSameSite=none（旧来のデフォルト）
example.jpのCookieをtrap.example.com

trap.example.com（罠サイト）

POST,GET

常に送信

SameSite=Lax（Google Chromeの現在のデフォルト）
example.jpのCookieをSameSite=Strict

POST,GET

GETのみ送信example.com

example.jp（攻撃対象サイト）

example.jpのCookieをPOST,GET
徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

一切送信しない34

2.クロスサイトスクリプティング(XSS)

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

35クロスサイトスクリプティングのイメージ（正常系）
利用者

シェイクスピアの本を検索しよう?author=Shakespeare

ウェブサーバー

検索結果…

蔵書検索結果著者名: Shakespeare
……………
……………
……………

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

36クロスサイトスクリプティングのイメージ（攻撃）図書館からのお知らせ○○様、至急ご確認ください
https://xxxxxxx/?author=<sci

利用者?author=<script>…

ウェブサーバー

検索結果…
<script> …

蔵書検索結果
著者名:
……………
……………
……………

徳丸浩のウェブセキュリティ講座<h1>蔵書検索結果</h1><p>著者名<script> /* 攻撃コード */ </script>© 2023 Hiroshi Tokumaru

37クロスサイトスクリプティングの影響• 攻撃を受けた人のパソコンが遠隔操作される– なりすまし投稿– なりすましの買い物– 情報漏えい• 影響は、脆弱性のあるサイト全体に及びます– 「重要でない」ページに影響があっても、個人情報漏洩なども起こりえる• 他のサイトには直接影響はない• 攻撃を受けた人（サイトを閲覧した人）のみに影響は限られる

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

38

対策

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

39

XSSの対策（根本的解決策）• 文脈に応じてHTMLエスケープ< → &lt;> → &gt;& → &amp;" → &quot;' → &#39; または &apos;• 属性値はダブルクオートで囲む• URLを取る属性値はスキームのチェックを行う– http: または https: または /• レスポンスヘッダで文字エンコーディングを指定– Content-Type: text/html; charset=UTF-8• JavaScriptの動的生成を避ける– HTML上に値を書いてJavaScriptから参照– JavaScriptのエスケープは人類には難しすぎる
徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

40対策後のプログラム（PHP）<?php
session_start();// ログインチェック（略）?><body>
検索キーワード:<?php echo htmlspecialchars($_GET['keyword']); ?><BR>
以下略</body>
クエリ文字列として <script>alert(document.cookie)</script> が入力された場合、表示は以下となる
検索キーワード:&lt;script&gt;alert(document.cookie)&lt;/script&gt;

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

41

XSSの対策（保険的対策）• CookieにHttpOnly属性を付与する– CookieにHttpOnly属性を付与すると、JavaScriptからCookieにアクセス禁止に– 他の方法で攻撃できるので、効果は限定的• X-XSS-Protection 以下を設定する– X-XSS-Protection: 1; mode=block※ Google Chrome、Firefox、Safariでは無効化されている• TRACEメソッドの無効化– XSSの応用としてCross Site Tracingがあり、TRACEメソッドの無効化により対策する（ただし、ブラウザ側で対策されているので実害はない）– Apacheでの設定: TraceEnable Off– Nginxでは元々無効化されているので対策不要

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

42

まとめ• ブラウザには、サンドボックス、同一生成元ポリシー(SOP)などの保護機能がある• SOPの保護機能により、正規サイトと「怪しいサイト」はアクセスが遮断されている• XSSは、SOPの保護機能の元で、正規サイトの情報に、「怪しいサイト」からアクセスできる（これはアプリケーションの脆弱性）• XSSがあると、ワナサイトを閲覧した利用者の個人情報が漏洩– あるいは「なりすまし犯行予告」の書き込みをさせることも…
• XSS対策の基本は、「終端」となる記号の文脈に応じたエスケープ• でも、色々ややこしいので参考文献で勉強を

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

43

3.SQLインジェクション

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

44

SQLインジェクションのイメージ（正常系）
データセンター / クラウド
利用者
シェイクスピアの本を検索しよう

ウェブサーバー

データベースサーバー?author=Shakespeare

SELECT * FROM books WHERE
author='Shakespeare'
蔵書検索
著者 Shakespeare
検索

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

45

SQLインジェクションのイメージ（攻撃）データセンター / クラウド
利用者
ウェブサーバー?author=';DELETE+FROM+
books+--+

データベースサーバー

SELECT * FROM books WHERE name='';DELETE FROM books -- '蔵書検索
DELETE文によりbooksテーブルの中身が削除される

著者 ';DELETE FROM books--

検索

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

46

SQLインジェクションの影響• データベース内のすべての情報が漏洩する– アプリケーションがSQL呼び出しに使うデータベースユーザの権限による• データの改変、削除• データベースサーバー内のファイルの読出し、書込み（設定による）• OSコマンドの実行（設定による）• 認証機能の回避

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

47

SQLインジェクションの対策• 根本的解決策– SQL文を動的に組み立てない– プレースホルダによりSQL文を組み立てる– フレームワークのO/Rマッパーなどを正しく使う• 保険的対策– 入力値の妥当性検証– 詳細なエラーメッセージの抑止– データベースのアクセスユーザに必要最低限の権限を割り当てる

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

48

プレースホルダによる対策例（PHP）<?php$author = $_GET['author']; // クエリ文字列から著者名を取得$db = … // データベース接続// 静的プレースホルダを使う設定$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);// ? はプレースホルダ$sql = "SELECT * FROM books WHERE author = ?";$dbh = $db->prepare($sql); // SQLを準備する$dbh->bindValue(1, $author, PDO::PARAM_STR); // バインド
$ps = $db->execute(); // クエリ実行
徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

49

ご清聴ありがとうございました

徳丸浩のウェブセキュリティ講座© 2023 Hiroshi Tokumaru

50