web-app-security-audit について
Web Application Security Audit は、Web アプリを開発・レビューする人向けの段階的なペネトレーションテストスキルです。10 段階でアプリケーション層を検査し、具体的なテストと深刻度付きの指摘を示します。許可のない対象やネットワーク層の検査には適しません。
主な機能
- 0110 段階の監査をガイド
- 02ルートと攻撃対象領域の整理
- 03認証とアクセス制御の検査
- 04一般的なインジェクションリスクの確認
- 05指摘の評価と要約
活用シーン
- 01本番導入前のアプリレビュー
- 02認証や決済機能の追加後の再確認
- 03定期的なアプリケーション層レビュー
- 04疑わしい Web 脆弱性の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ ahmedhamadto/ software-forge --skill web-app-security-auditインストール後、Claude Code で/web-app-security-auditを入力して読み込まれたか確認します。
詳細
Web アプリケーションのセキュリティ監査
概要
The Web Application Hacker's Handbook に基づく、体系的なペネトレーションテストの手法です。構築中またはレビュー中のあらゆる Web アプリケーションの脆弱性を体系的に特定できるよう、10 の段階を順番に進めます。
使用するタイミング
- Web アプリケーションを本番環境にデプロイする前
- 認証、決済処理、またはユーザー向け機能を追加するとき
- 定期的なセキュリティレビュー中
- サードパーティのサービスや API を統合した後
- 特定の脆弱性の種類を疑っているものの、包括的に調査したいとき
使用しないタイミング
- 所有していない、またはテストの許可を得ていないアプリケーションに対して
- 重要なシステムに対する専門的なペネトレーションテストの代わりとして
- ネットワークレベルのセキュリティに対して(この手法はアプリケーション層に重点を置いています)
プロセス
各段階を順番に進めます。各段階で、次のことを行います。
- 対象のアプリケーションに関する具体的な質問をします
- 詳細なガイダンスを得るため、
cybersecurity/web-application-hackers-handbook/から該当する章の概要を読みます - 具体的なテスト(ソースコード内の grep パターン、curl コマンド、Burp Suite の手順、自動化スクリプトなど)を提案し、実行します
- 検出事項に重大度を付けます:
CRITICAL/HIGH/MEDIUM/LOW/INFO - 次の段階に進む前に、検出事項を要約します
その段階に該当する領域がアプリケーションにない場合(例:ファイルアップロード機能がない場合)は、その旨を認め、理由を説明してスキップします。
digraph audit_phases {
rankdir=TB;
node [shape=box, style=rounded];
p1 [label="Phase 1\nMap the Application"];
p2 [label="Phase 2\nAnalyze the Application"];
p3 [label="Phase 3\nClient-Side Controls"];
p4 [label="Phase 4\nAuthentication"];
p5 [label="Phase 5\nSession Management"];
p6 [label="Phase 6\nAccess Controls"];
p7 [label="Phase 7\nInjection Vulnerabilities"];
p8 [label="Phase 8\nApplication Logic"];
p9 [label="Phase 9\nApplication Server"];
p10 [label="Phase 10\nReview & Report"];
report [label="Security Audit\nReport", shape=note];
p1 -> p2 -> p3 -> p4 -> p5 -> p6 -> p7 -> p8 -> p9 -> p10 -> report;
}
フェーズ 1:アプリケーションをマッピングする
参照先: cybersecurity/web-application-hackers-handbook/ch04-mapping-the-application.md
目標: テストを始める前に、攻撃対象領域全体を把握します。
質問:
- アプリケーションの技術スタックは何ですか?(フレームワーク、言語、データベース、ホスティング環境)
- すべてのルート/エンドポイントはどれですか?(ルートファイル、API 定義、OpenAPI 仕様を確認)
- 管理パネル、API ドキュメント、デバッグ用エンドポイントはありますか?
- どのようなサードパーティサービスが統合されていますか?
実施するテスト:
- ソースコードからすべてのルートを列挙します:
# Express.js grep -rn "app\.\(get\|post\|put\|delete\|patch\)" --include="*.ts" --include="*.js" # Django grep -rn "path\|url(" --include="*.py" urls.py # Rails grep -rn "get\|post\|put\|delete\|patch\|resources\|resource" config/routes.rb # Next.js — check app/ and pages/ directory structure - 公開されているファイルを確認します:
robots.txt、sitemap.xml、.env、.git/、package.json - ソース内にハードコードされたシークレットがないか検索します:
grep -rni "password\|secret\|api_key\|token\|private_key" --include="*.ts" --include="*.js" --include="*.py" --include="*.env*" - HTML/JS のコメントに機密情報が含まれていないか確認します
- すべての入力経路を特定します:URL パラメーター、POST ボディ、Cookie、ヘッダー、ファイルアップロード、WebSocket
成果物: 攻撃対象領域の全体マップ — ルート、パラメーター、テクノロジー、侵入経路。
フェーズ 2:アプリケーションを分析する
参照先: cybersecurity/web-application-hackers-handbook/ch03-web-application-technologies.md
目標: アプリケーションの機能を理解し、リスクの高い領域を特定します。
質問:
- 中核となる業務機能は何ですか?(ユーザー管理、決済、データの CRUD、検索、ファイル処理)
- どの機能が機密データを扱いますか?(PII、財務情報、認証情報)
- 複数の手順からなるプロセスはありますか?(チェックアウト、登録、承認ワークフロー)
- どのようなユーザーロールがありますか?各ロールで何ができますか?
テストの優先順位(リスクの高い順):
- 認証と認証情報の取り扱い
- 決済/金融取引の処理
- ファイルアップロード機能
- 管理インターフェース
- API エンドポイント(Web UI より制御が弱いことがよくあります)
- 検索機能(インジェクションの標的になりやすい機能)
- ユーザー間機能(格納型 XSS の経路)
- データのエクスポート/インポート(インジェクション、XXE)
成果物: リスクに基づいて関心領域の優先順位を付けた、機能マップ。
フェーズ 3:クライアント側の制御をテストする
参考資料: cybersecurity/web-application-hackers-handbook/ch05-bypassing-client-side-controls.md
目標: サーバーがクライアント側の検証や状態を決して信頼しないことを確認します。
確認する質問:
- サーバーが依存している隠しフォームフィールドはありますか?(価格、ロール、ユーザー ID)
- 入力検証はクライアント側でのみ行われていますか?(JavaScript、HTML5 属性)
- クライアントはサーバー側で管理すべきデータを送信していますか?(カートの合計、割引フラグ、権限レベル)
実行するテスト:
- 隠しフィールドを検索します:
grep -rn 'type="hidden"\|type=.hidden.' --include="*.html" --include="*.tsx" --include="*.jsx" - クライアント側のみの検証を検索します:
grep -rn "maxlength\|pattern=\|required\b" --include="*.html" --include="*.tsx" --include="*.jsx" - サーバー側の検証がクライアント側の検証と一致しているか確認します:
grep -rn "validate\|sanitize\|zod\|yup\|joi\|class-validator" --include="*.ts" --include="*.js" --include="*.py" - 各フォームで、必須フィールドの欠落、maxlength を超える値、パターンに違反する値、変更した隠しフィールドを含むリクエストを送信します
- リクエスト本文を変更して、価格/ロール/権限の改ざんをテストします
検出事項のテンプレート:
[SEVERITY] Client-Side Control Bypass: [description]
Affected: [endpoint/parameter]
Test: [what you did]
Result: [what happened]
Impact: [what an attacker could achieve]
Fix: [server-side validation recommendation]
フェーズ 4:認証をテストする
参考資料: cybersecurity/web-application-hackers-handbook/ch06-attacking-authentication.md
目標: 認証を回避、ブルートフォース攻撃、悪用できないことを確認します。
実行するテスト:
ユーザー名の列挙:
- ログイン、登録、パスワードリセットで、有効なユーザー名と無効なユーザー名に対する応答を比較します
- 応答本文、ステータスコード、応答時間の差、応答の長さを確認します
- 一貫性のないエラーメッセージを検索します:
grep -rn "invalid.*username\|user.*not found\|no.*account\|incorrect.*password" --include="*.ts" --include="*.js" --include="*.py"
ブルートフォース攻撃への耐性:
- アカウントロックアウト、レート制限、CAPTCHA を確認します
- レート制限の実装を検索します:
grep -rn "rate.limit\|throttle\|brute\|lockout\|max.*attempts" --include="*.ts" --include="*.js" --include="*.py"
パスワードポリシー:
- 最小文字数、複雑さの要件、一般的なパスワードの拒否をテストします
- パスワードの保存方法を確認します:
grep -rn "bcrypt\|argon2\|scrypt\|pbkdf2\|sha256\|sha1\|md5\|plaintext" --include="*.ts" --include="*.js" --include="*.py" - パスワードがソルトなしの平文、MD5、または SHA1 で保存されている場合は
CRITICALです
パスワードリセット:
- トークンのランダム性、有効期限、1 回限りの使用が強制されているか確認します
- リセットトークンが URL に含まれているか確認します(サーバーログやブラウザー履歴に記録されます)
多要素認証:
- 認証済みエンドポイントに直接リクエストすることで、MFA のステップをスキップできますか?
- コードを再送信したり、期限切れのコードを使用したりして、MFA を回避できますか?
ログイン状態を保持する機能:
- ログイン状態を保持するトークンをデコードします(Base64、JWT)。ユーザー情報が含まれていますか?
- パスワード変更時に無効化されますか?
フェーズ 5:セッション管理をテストする
参考資料: cybersecurity/web-application-hackers-handbook/ch07-attacking-session-management.md
目標: セッションのハイジャック、固定化、予測ができないことを確認します。
実行するテスト:
トークンの生成:
- 複数のセッショントークンを収集し、パターン(連番、タイムスタンプベース、低エントロピー)がないか確認します
- トークンをデコードします(Base64、JWT)。機密データが含まれていますか?
# For JWTs grep -rn "jwt\|jsonwebtoken\|jose" --include="*.ts" --include="*.js" --include="*.py"
Cookie フラグ:
- すべての Cookie で
Secure、HttpOnly、SameSite、Domain、Pathを確認しますgrep -rn "Set-Cookie\|cookie\|setCookie\|httpOnly\|secure\|sameSite" --include="*.ts" --include="*.js" --include="*.py" - セッション Cookie に
HttpOnlyがない場合はHIGHです(XSS によって盗まれる可能性があります) - セッション Cookie に
Secureがない場合はHIGHです(HTTP 経由で送信されます) - セッション Cookie に
SameSiteがない場合はMEDIUMです(CSRF の攻撃経路になります)
セッションのライフサイクル:
- ログイン後にトークンは変わりますか?(変わらない場合はセッション固定化の可能性があります)
- ログアウト時にサーバー側でセッションが無効化されますか?(Cookie を削除するだけではありません)
- アイドルタイムアウトと絶対タイムアウトはありますか?
CSRF 対策:
- 状態を変更するすべての操作(POST/PUT/DELETE)を特定します
- CSRF 対策トークンを確認します:
grep -rn "csrf\|xsrf\|_token\|csrfmiddleware" --include="*.ts" --include="*.js" --include="*.py" --include="*.html" - CSRF トークンなしで状態変更リクエストを成功させられますか?
フェーズ 6:アクセス制御をテストする
参考: cybersecurity/web-application-hackers-handbook/ch08-attacking-access-controls.md
目標: ユーザーが、許可されていないデータや機能にアクセスできないことを確認します。
確認する質問:
- どのようなユーザーロールがありますか?(admin、user、moderator、API consumer)
- 認可はどのように適用されていますか?(ミドルウェア、デコレーター、インラインチェック)
- URL やリクエストボディに、改ざん可能なリソース ID はありますか?
実行するテスト:
IDOR(安全でない直接オブジェクト参照):
- リソース ID を含むすべてのエンドポイントを見つけます:
grep -rn "/users/\|/orders/\|/documents/\|/api/.*/:id\|/api/.*/<.*>" --include="*.ts" --include="*.js" --include="*.py" - ユーザー A として、ID を変更してユーザー B のリソースをリクエストします
- 成功した場合は
CRITICALです
垂直権限昇格:
- 一般ユーザーとして、管理者用エンドポイントを直接リクエストします
- エンドポイントごとに認可が適用されているか確認します:
grep -rn "isAdmin\|requireAdmin\|role.*admin\|authorize\|permission\|@Roles\|@RequiresRole" --include="*.ts" --include="*.js" --include="*.py" - 認可ミドルウェアが適用されていないエンドポイントがないか確認します
水平権限昇格:
- リクエスト内のユーザー識別パラメーター(
user_id、account_id、email)を変更します - リクエストされたリソースが認証済みユーザーに属していることをサーバーが検証しているか確認します
複数ステップのプロセス制御:
- 複数ステップのフロー(チェックアウト、承認)では、後続のステップに直接進んでスキップできるかテストします
- ステップを順序どおりに実行しなくてもよいかテストします
フェーズ 7:インジェクションの脆弱性をテストする
参考: cybersecurity/web-application-hackers-handbook/ch09-attacking-data-stores.md、ch10-attacking-back-end-components.md、ch12-attacking-users-xss.md
目標: あらゆるコンテキストで、すべての入力が安全に処理されることを確認します。
SQL インジェクション:
# Find raw query construction (CRITICAL pattern)
grep -rn "query.*+\|execute.*+\|raw.*+\|\\.format.*SELECT\|f\".*SELECT\|f'.*SELECT" --include="*.ts" --include="*.js" --include="*.py"
# Verify parameterized queries are used
grep -rn "prepare\|parameterized\|\$[0-9]\|placeholder\|\?" --include="*.ts" --include="*.js" --include="*.py"
- SQL クエリで文字列連結や文字列補間が使われている場合は
CRITICALです
XSS(クロスサイトスクリプティング):
# Find dangerous DOM operations
grep -rn "innerHTML\|outerHTML\|document\.write\|\.html(\|dangerouslySetInnerHTML\|v-html\|\{!! " --include="*.ts" --include="*.js" --include="*.tsx" --include="*.jsx" --include="*.vue" --include="*.blade.php"
# Find eval usage
grep -rn "eval(\|Function(\|setTimeout.*string\|setInterval.*string" --include="*.ts" --include="*.js"
- 保存型 XSS は
HIGH、反射型 XSS と DOM ベース XSS はMEDIUMです
OS コマンドインジェクション:
grep -rn "exec(\|execSync\|spawn(\|system(\|popen\|subprocess\|child_process\|shell_exec\|passthru\|backtick" --include="*.ts" --include="*.js" --include="*.py" --include="*.php"
- ユーザー入力がコマンド実行に渡される場合は
CRITICALです
パストラバーサル:
grep -rn "readFile\|writeFile\|createReadStream\|open(\|path\.join.*req\|path\.resolve.*req\|fs\." --include="*.ts" --include="*.js" --include="*.py"
- サニタイズされていないユーザー入力がファイルパスに使われていないか確認します
XXE(XML 外部実体):
grep -rn "parseXML\|DOMParser\|SAXParser\|XMLReader\|etree\.parse\|xml2js\|libxml" --include="*.ts" --include="*.js" --include="*.py"
- 外部実体の処理が無効になっているか確認します
SSRF(サーバーサイドリクエストフォージェリ):
grep -rn "fetch(\|axios\|request(\|urllib\|http\.get\|https\.get\|curl\|wget" --include="*.ts" --include="*.js" --include="*.py"
- ユーザーが指定した URL が許可リストに照らして検証されているか確認します
- ユーザー入力が検証されずにサーバー側の HTTP リクエストに直接渡される場合は
CRITICALです
サーバーサイドテンプレートインジェクション(SSTI):
grep -rn "render_template_string\|Template(\|Jinja2\|nunjucks.*render\|handlebars.*compile\|ejs.*render" --include="*.ts" --include="*.js" --include="*.py"
- ユーザー入力がレンダリング前にテンプレートへ埋め込まれていないか確認します
フェーズ 8:アプリケーションロジックをテストする
参考: cybersecurity/web-application-hackers-handbook/ch11-attacking-application-logic.md
目標: 自動スキャナーでは検出できないビジネスロジックの欠陥を特定します。
確認する質問:
- 各関数は、ユーザーの行動についてどのような前提を置いていますか?
- 複数ステップのプロセスはありますか? ステップをスキップしたり、順序を入れ替えたりできますか?
- 金銭の取引はありますか? 金額を改ざんできますか(負の値、ゼロ、オーバーフロー)?
- 紹介・報酬・クーポンの仕組みはありますか? 悪用される可能性はありますか?
実行するテスト:
競合状態:
grep -rn "balance\|credits\|quantity\|stock\|inventory\|coupon\|redeem\|transfer\|withdraw" --include="*.ts" --include="*.js" --include="*.py"
- あらゆる確認後に実行するパターン(残高の確認 → 減算)で、並行リクエストをテストします
- 二重支払いや二重引き換えが可能な場合は
HIGHです
複数ステップのプロセスの悪用:
- すべての複数ステップフロー(チェックアウト、登録、承認)をマッピングします
- 次の項目をテストします:ステップのスキップ、繰り返し、前のステップへの移動、ステップ間のデータ変更、ステップ間のユーザーコンテキストの切り替え
トランザクションロジック:
- 負の金額、ゼロの金額、極端に大きな金額をテストします
- 整数が想定される箇所で、小数値をテストします
- 自己紹介や循環する紹介チェーンをテストします
入力正規化の不整合:
- Unicode 正規化の問題(同じ文字の異なる表現)をテストします
- 大文字と小文字の区別に関する不整合をテストします(「admin」が存在する場合に「Admin」として登録する)
フェーズ 9:アプリケーションサーバーのテスト
参考資料: cybersecurity/web-application-hackers-handbook/ch18-attacking-the-application-server.md
目標: サーバープラットフォーム自体が強化されていることを確認します。
実行するテスト:
デフォルトの認証情報:
/admin、/wp-admin、/phpmyadmin、/console、/managerなど、一般的なパスに管理パネルが存在するか確認します- 見つかった管理インターフェースで、デフォルトの認証情報を試します
危険な HTTP メソッド:
curl -X OPTIONS <target-url> -i
- PUT、DELETE、TRACE が不必要に有効になっている場合は
MEDIUM
セキュリティヘッダー:
curl -s -I <target-url>
次を確認します:
Content-Security-Policy— 欠落している場合はHIGH(XSS の緩和)Strict-Transport-Security— 欠落している場合はHIGH(HTTPS の強制)X-Frame-Optionsまたは CSP のframe-ancestors— 欠落している場合はMEDIUM(クリックジャッキング対策)X-Content-Type-Options: nosniff— 欠落している場合はLOW(MIME スニッフィング対策)Referrer-Policy— 欠落している場合はLOW(情報漏えい対策)Permissions-Policy— 欠落している場合はINFOServer/X-Powered-By— 存在する場合はINFO(バージョンの開示)
デバッグモード:
grep -rn "DEBUG.*=.*True\|debug.*:.*true\|NODE_ENV.*development\|FLASK_DEBUG\|DJANGO_DEBUG" --include="*.py" --include="*.js" --include="*.ts" --include="*.env*" --include="*.yaml" --include="*.yml"
- 本番環境の設定でデバッグモードが有効になっている場合は
HIGH
依存関係の脆弱性:
# Node.js
npm audit
# Python
pip-audit # or safety check
# Ruby
bundle audit
既知の CVE:
- フレームワーク/ライブラリのバージョンを既知の脆弱性と照合します
- RCE の CVE は
CRITICAL、認証バイパスの CVE はHIGH
フェーズ 10:レビューとレポート
参考資料: cybersecurity/web-application-hackers-handbook/ch15-exploiting-information-disclosure.md、ch21-web-application-hackers-methodology.md
最終確認:
情報開示:
grep -rn "console\.log\|print(\|logger\.\(debug\|info\)\|TODO\|FIXME\|HACK\|XXX" --include="*.ts" --include="*.js" --include="*.py"
- 内部情報を露呈する詳細なエラーメッセージがないか確認します
.git/、.env、ソースマップ、バックアップファイルが公開されていないか確認します
SSL/TLS:
# If accessible externally
nmap --script ssl-enum-ciphers -p 443 <target>
# Or use testssl.sh
監査レポートを生成します:
# Security Audit Report: [Application Name]
**Date:** [date]
**Auditor:** [name]
**Scope:** [what was tested]
## Executive Summary
[1-2 paragraph summary of overall security posture and critical findings]
## Findings Summary
| # | Severity | Finding | Phase |
|---|----------|---------|-------|
| 1 | CRITICAL | [title] | [phase] |
| 2 | HIGH | [title] | [phase] |
| ... | ... | ... | ... |
## Detailed Findings
### Finding 1: [Title]
**Severity:** CRITICAL / HIGH / MEDIUM / LOW / INFO
**Phase:** [which phase found it]
**Affected Component:** [endpoint, file, function]
**Description:**
[What the vulnerability is and why it exists]
**Reproduction Steps:**
1. [Step-by-step to reproduce]
**Impact:**
[What an attacker could achieve — data access, account takeover, RCE, etc.]
**Remediation:**
[Specific, actionable fix with code example if possible]
**Reference:**
[OWASP, CWE, or WAHH chapter reference]
---
[Repeat for each finding]
## Recommendations Priority
1. [Fix critical/high findings immediately]
2. [Fix medium findings before next release]
3. [Fix low/info findings as part of regular maintenance]
## Out of Scope / Not Tested
[What was explicitly excluded and why]
深刻度評価ガイド
| 深刻度 | 基準 | 例 |
|---|---|---|
| CRITICAL | 即時に悪用可能、RCE、完全なデータ侵害、認証バイパス | データにアクセス可能な SQL インジェクション、コマンドインジェクションによる RCE、ハードコードされた管理者認証情報、認証なしの管理者アクセス |
| HIGH | 重大なデータ露出、アカウント乗っ取り、権限昇格 | 格納型 XSS、機密データに対する IDOR、不適切なアクセス制御、セッション固定、HTTPS 強制の欠如 |
| MEDIUM | 限定的な悪用、ユーザー操作が必要、一部のデータ露出 | 反射型 XSS、重要度の低い機能に対する CSRF、SameSite Cookie の欠如、内部パスを含む詳細なエラーメッセージ |
| LOW | 軽微な情報開示、ベストプラクティス違反 | ヘッダーでのバージョン開示、X-Content-Type-Options の欠如、機密フィールドでのオートコンプリート |
| INFO | 観察事項、直接的なセキュリティへの影響なし | Permissions-Policy の欠如、軽微な設定上の注意事項、多層防御のための提案 |
よくある間違い
| 間違い | 修正方法 |
|---|---|
| 正常系のパスだけをテストする | すべてのパラメーターに悪意のある入力を試します。インジェクションは境界条件に潜んでいます |
| アクセス制御のテストを省略する | IDOR は一貫して上位の脆弱性です。ユーザーコンテキストを変えて、すべてのリソースエンドポイントをテストします |
| UI 経由でのみテストする | UI ではパラメーター、エンドポイント、機能が隠されています。API を直接テストします |
| フレームワークがセキュリティを処理してくれると思い込む | フレームワークが提供するのはツールであり、保証ではありません。各メカニズムが正しく設定され、使用されていることを確認します |
| 個別にテストする | 発見事項を組み合わせます。情報開示 + IDOR + XSS により、深刻度が LOW から CRITICAL まで上がる可能性があります |
| カテゴリーごとに最初の発見でテストを終了する | SQL インジェクションが 1 つ見つかっても、すべてのクエリが脆弱とは限りません。各エンドポイントを個別にテストします |