🔍
Webアプリセキュリティテスト実践(Burp Suite・SAST・DAST)
セキュリティテストの全体像
セキュリティテストの種類:
SAST(Static Application Security Testing)
└── コードを実行せず静的解析でバグを検出
ツール: Semgrep, Bandit, CodeQL, Checkmarx
DAST(Dynamic Application Security Testing)
└── 動作中のアプリに実際にリクエストを送って脆弱性を検出
ツール: OWASP ZAP, Burp Suite Pro(Scanner), Nikto
IAST(Interactive AST)
└── 実行中のアプリにエージェントを埋め込んでリアルタイム検出
ツール: Contrast Security, Seeker
ペネトレーションテスト(手動)
└── テスターが攻撃者の視点で能動的に脆弱性を探す
フレームワーク: OWASP WSTG, PTES
SCA(Software Composition Analysis)
└── 依存ライブラリの既知 CVE を検出
ツール: Trivy, Dependabot, Snyk
Burp Suite 実践
基本セットアップ
1. Burp Suite Community / Pro を起動
2. Proxy → Options → Proxy Listeners: 127.0.0.1:8080
3. ブラウザのプロキシ設定を 127.0.0.1:8080 に向ける
(推奨: Burp の組み込みブラウザを使う)
4. Burp の CA 証明書をブラウザにインポート
→ http://burp → CA Certificate をダウンロード → ブラウザにインストール
5. Proxy → Intercept → ON でリクエストをキャプチャ開始
Proxy でのインターセプト操作
主要ショートカット:
Ctrl+F → Forward(リクエストを転送)
Drop → リクエストを破棄
Action → Send to Repeater(Ctrl+R)
Action → Send to Intruder(Ctrl+I)
Proxy History でリクエスト一覧を確認:
・Filter で特定のホスト・ステータスコードに絞り込み
・右クリック → Send to Repeater で詳細テスト
Repeater(手動リクエスト改ざん)
使い方:
1. Proxy History から気になるリクエストを Repeater に送る
2. リクエストのパラメータを手動で変更して Send
3. レスポンスを比較して脆弱性を確認
テスト例(SQLi 確認):
元: GET /api/users?id=1
改: GET /api/users?id=1' ← SQL エラーが返れば SQLi の可能性
改: GET /api/users?id=1 OR 1=1--
改: GET /api/users?id=1 AND SLEEP(5)-- ← Blind SQLi
Intruder(自動化・ブルートフォース)
使い方:
1. Repeater で使うリクエストを Intruder に送る
2. Positions タブでペイロードを挿入する位置を § マーカーで囲む
3. Payloads タブでリストまたはパターンを設定
4. Start Attack でリクエストを一括送信
Attack タイプ:
Sniper: 1つの位置に順番にペイロードを挿入
Battering ram: 全位置に同じペイロードを同時挿入
Pitchfork: 各位置に異なるリストを並行挿入(user + password の組み合わせ)
Cluster bomb: 全位置に全組み合わせ挿入(総当たり)
Community 版の制限: Intruder はスロットリングあり → Pro 版推奨
Scanner(Pro 版のみ)
受動スキャン: Proxy を通過するすべてのリクエストを自動分析
能動スキャン: 対象 URL に積極的に攻撃ペイロードを送信して脆弱性を検出
スキャン手順:
1. Target → Site Map で対象ホストを確認
2. 対象ホストを右クリック → Active Scan
3. スキャン完了後、Dashboard → Issues で結果を確認
重要度(Severity):
High: 即座に対処が必要(SQLi, RCE, 認証バイパス)
Medium: 対処推奨(XSS, SSRF)
Low: コンテキスト依存(情報漏洩, ヘッダー欠如)
Info: 参考情報(バージョン情報, パス列挙)
Decoder / Comparer
Decoder:
・Base64 / URL エンコード / HTML エンティティ / 16進数 を相互変換
・JWT のペイロード部分(Base64url)を貼り付けてデコード
・Use: Proxy でトークンをコピー → Decoder に貼り付け → Decode as Base64
Comparer:
・2つのレスポンスの差分を視覚的に比較
・Use: レスポンスの長さが異なる場合に Blind SQLi の結果を比較
OWASP WSTG に沿った手動テスト
OWASP Web Security Testing Guide(WSTG)はセキュリティテストの標準手順書。
情報収集(Reconnaissance)
# サブドメイン列挙
subfinder -d example.com
amass enum -d example.com
# ポートスキャン・サービス検出
nmap -sV -sC -p 80,443,8080,8443 example.com
# ディレクトリ・ファイルのブルートフォース
gobuster dir -u https://example.com -w /usr/share/wordlists/dirb/common.txt
ffuf -u https://example.com/FUZZ -w wordlist.txt -mc 200,301,302,403
# Wayback Machine でページ履歴を確認(廃止 API の発見)
waybackurls example.com | grep "api"
# JS ファイルから隠しエンドポイントを抽出
cat *.js | grep -E "(api|endpoint|url|path)" | sort -u
認証テスト
WSTG-AUTHN-01: 暗号化されていない認証チャネルのテスト
→ HTTP でログインページが提供されていないか確認
→ HSTS が設定されているか確認
WSTG-AUTHN-03: アカウントロックアウトのテスト
Burp Intruder でパスワードをブルートフォース(許可された環境のみ)
→ 10回失敗後もロックアウトされないか確認
WSTG-AUTHN-06: ブラウザキャッシュの脆弱性テスト
→ ログアウト後に「戻る」ボタンで画面が表示されないか
→ Cache-Control: no-store が設定されているか
# パスワードリセットのテスト手順
"""
1. パスワードリセットを要求 → メールのトークンを取得
2. トークンの長さ・エントロピーを確認(最低 128bit = 16バイト)
3. トークンを使用後に無効化されるか確認(2度使えないか)
4. 有効期限を確認(1時間以内が推奨)
5. ユーザー名を変えて同じトークンが使えないか確認
"""
セッション管理テスト
WSTG-SESS-01: セッション管理スキームの分析
Burp Sequencer でセッション ID のランダム性を統計的に評価:
1. Proxy でログインリクエストをキャプチャ
2. Set-Cookie の値を Sequencer に送る
3. Start Live Capture → 1000件のセッション ID を収集
4. Analyze → Information content(ビット数)を確認
→ 100bit 未満であれば予測可能なリスク
WSTG-SESS-02: Cookie 属性のテスト
Proxy でレスポンスの Set-Cookie ヘッダーを確認:
□ HttpOnly が設定されているか
□ Secure が設定されているか
□ SameSite が Strict または Lax か
□ 有効期限が適切か
WSTG-SESS-06: ログアウト機能のテスト
1. ログイン → セッション Cookie を記録
2. ログアウト
3. 記録したセッション Cookie を手動でセットして API にアクセス
→ サーバー側でセッションが無効化されているか確認
認可テスト(IDOR・権限昇格)
WSTG-ATHZ-01: ディレクトリトラバーサルのテスト
Burp Repeater でファイルパスのパラメータを改ざん:
/api/files/report.pdf → /api/files/../../../etc/passwd
/api/files/report.pdf → /api/files/%2e%2e%2f%2e%2e%2fetc%2fpasswd(URL エンコード)
WSTG-ATHZ-04: 水平・垂直権限昇格テスト
1. User A と User B の2アカウントを用意
2. User A の認証 Cookie / JWT を使って User B のリソースにアクセス
GET /api/orders/B_ORDER_ID with A's token → 403 を返すはず
3. 管理者 URL を推測してアクセス
/api/admin/users, /api/v1/admin, /api/internal
インジェクションテスト
SQLi の手動テスト:
1. 単一引用符: ' → SQL エラーを確認
2. トートロジー: 1 OR 1=1 → 全件取得されないか
3. コメント: 1-- 1# 1;-- → SQL 構文の残りをコメントアウト
4. Union: ' UNION SELECT NULL-- → カラム数を特定
5. Time-based: ' AND SLEEP(5)-- → 応答遅延で Blind SQLi を確認
XSS の手動テスト:
基本ペイロード:
<script>alert(1)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
属性インジェクション:
" onmouseover="alert(1)
"><script>alert(1)</script>
DOM XSS の確認:
ブラウザコンソールで document.getElementById('output').innerHTML を確認
URL パラメータが innerHTML / document.write に渡っていないか調査
SAST(静的解析)ツール
Semgrep
# .semgrep.yml: カスタムルール例(危険な eval の検出)
rules:
- id: dangerous-eval
pattern: eval(...)
message: "eval() の使用はコードインジェクションのリスクがあります"
languages: [javascript, typescript]
severity: WARNING
- id: sql-injection-string-concat
pattern: |
$QUERY = "SELECT ... " + $INPUT
message: "文字列結合によるSQLクエリはSQLインジェクションのリスクがあります"
languages: [python]
severity: ERROR
# 実行
semgrep --config=auto src/ # 公式ルールセットで自動スキャン
semgrep --config=.semgrep.yml src/ # カスタムルールで実行
# CI(GitHub Actions)への組み込み
# .github/workflows/semgrep.yml
# GitHub Actions での Semgrep 統合
name: Semgrep SAST
on: [push, pull_request]
jobs:
semgrep:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: semgrep/semgrep-action@v1
with:
config: >-
p/security-audit
p/owasp-top-ten
p/python
Bandit(Python 専用)
# インストール
pip install bandit
# スキャン
bandit -r src/ -f json -o bandit-report.json
# 重大度・信頼度でフィルタ
bandit -r src/ -l # 高重大度のみ
bandit -r src/ -ll # 中以上の重大度
# 主要な検出項目
# B101: assert の使用(テストコード以外)
# B105: ハードコードされたパスワード
# B201: Flask のデバッグモードが有効
# B301: pickle の安全でない使用
# B501: SSL 証明書の検証を無効化
# B608: SQLi の可能性(文字列結合のクエリ)
DAST ツール
OWASP ZAP
# Docker で ZAP フルスキャン(CI 向け)
docker run --rm -v $(pwd):/zap/wrk/:rw \
ghcr.io/zaproxy/zaproxy:stable zap-full-scan.py \
-t https://example.com \
-r zap-report.html \
-J zap-report.json
# ベースラインスキャン(パッシブのみ、CI の PR チェック向け)
docker run --rm \
ghcr.io/zaproxy/zaproxy:stable zap-baseline.py \
-t https://staging.example.com \
-r baseline-report.html
# GitHub Actions での ZAP 統合
name: DAST Scan
on:
push:
branches: [main]
jobs:
zap_scan:
runs-on: ubuntu-latest
steps:
- name: ZAP Baseline Scan
uses: zaproxy/action-baseline@v0.12.0
with:
target: 'https://staging.example.com'
rules_file_name: '.zap/rules.tsv'
fail_action: false # 脆弱性があっても CI を落とさない(最初は warn のみ)
SCA(依存ライブラリのスキャン)
# Trivy(コンテナ・ファイルシステム・SBOM)
trivy fs --scanners vuln,secret . --format table
# npm audit
npm audit --audit-level=high
# pip-audit
pip install pip-audit
pip-audit -r requirements.txt
# GitHub Dependabot(自動 PR で依存更新)
# .github/dependabot.yml
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
Burp Suite 拡張(BApp Store)
必須インストール拡張:
DOM Invader:
・DOM XSS の Source / Sink を自動追跡
・Canary 文字列を埋め込んでどの Sink に到達したか検出
Param Miner:
・隠しパラメータ・ヘッダーをブルートフォースで発見
・Cache Poisoning の原因になる未知のキャッシュキーを発見
InQL(GraphQL Analyzer):
・GraphQL の Introspection を解析してクエリを自動生成
・Burp Suite と統合してインターセプト・テストが可能
JWT Editor:
・JWT の alg:none 攻撃・RS256→HS256 混同攻撃を自動でテスト
・ペイロードを改ざんして再署名
Active Scan++:
・Scanner の検出精度を向上させる追加チェック項目
テストのスコーピングと注意事項
必ず実施すること:
□ テスト対象のスコープを書面(テスト許可書)で取得する
□ 本番環境ではなくステージング環境でテストする
□ Burp Target → Scope で対象ホストを制限する(スコープ外に誤送信しない)
□ テスト中のアクションをログに記録する(証跡として残す)
□ 発見した脆弱性はすぐに報告する(悪用しない)
Burp でスコープを設定する手順:
1. Target → Scope → Add
2. テスト対象の URL を入力
3. Proxy → Options → "Out-of-Scope Requests" で警告を有効化
セキュリティテスト総合チェックリスト
認証・セッション
□ ログイン失敗に対してアカウントロックアウトまたはレートリミットがある
□ セッション ID が最低 128bit のエントロピーを持つ(Burp Sequencer で確認)
□ Cookie に HttpOnly・Secure・SameSite=Strict が設定されている
□ ログアウト後にサーバー側でセッションが無効化される
□ パスワードリセットトークンが使用後に無効化・有効期限がある
□ JWT の alg:none 攻撃・RS256/HS256 混同が成立しない(Burp JWT Editor で確認)
認可
□ 他ユーザーの ID を使ったオブジェクトアクセスが 403 を返す(IDOR テスト)
□ 一般ユーザーが管理者エンドポイントにアクセスできない
□ /api/admin, /api/internal, /api/v1/admin 等の URL を試した
□ HTTP メソッドを変えても(GET→POST→DELETE)認可が効いている
インジェクション
□ 全パラメータに単一引用符(')を入力してエラーが出ないことを確認
□ HTML 出力箇所に <script>alert(1)</script> を入力して実行されないことを確認
□ ファイルパスのパラメータに ../../../etc/passwd を試した
□ URL フェッチ機能に http://127.0.0.1/ を試した(SSRF)
セキュリティヘッダー
□ CSP ヘッダーが設定されている(securityheaders.com でスキャン)
□ HSTS が設定されている
□ X-Content-Type-Options: nosniff が設定されている
□ Server・X-Powered-By ヘッダーでバージョン情報が漏れていない
依存ライブラリ
□ npm audit / pip-audit / trivy fs で HIGH 以上の CVE がない
□ Dependabot または定期的な SCA スキャンを CI に組み込んでいる
参考文献
- OWASP Web Security Testing Guide v4.2(owasp.org/www-project-web-security-testing-guide)— Webアプリテストの標準手順書(全テストケース)
- PortSwigger Web Security Academy(portswigger.net/web-security)— Burp Suite を使ったインタラクティブ学習ラボ(無料)
- PortSwigger Burp Suite Documentation — Repeater・Intruder・Scanner の公式操作ガイド
- Dafydd Stuttard & Marcus Pinto『The Web Application Hacker’s Handbook』(Wiley, 2011)— 手動テスト手法の体系的解説
- Semgrep ドキュメント(semgrep.dev)— SAST ルールの書き方・公式ルールセット一覧
- 1. 🌍Webアプリセキュリティ概要
- 2. 💉インジェクション攻撃(SQLi・コマンド・XXE)
- 3. 📜XSS(クロスサイトスクリプティング)・CSP
- 4. 🪤CSRF・Clickjacking・CORS
- 5. 🚪認証・認可の実装ミス(セッション・JWT・OAuth)
- 6. 🔌API セキュリティ(REST・GraphQL・OWASP API Top 10)
- 7. 🛡️セキュリティヘッダー完全ガイド
- 8. 🔍Webアプリセキュリティテスト実践(Burp Suite・SAST・DAST)
出典: OWASP Testing Guide v4.2 / PortSwigger Burp Suite Documentation / OWASP WSTG / The Web Application Hacker's Handbook(Stuttard & Pinto, 2011)