performing-web-application-vulnerability-triage について
DAST と SAST のスキャン結果を確認する Web アプリケーション向けセキュリティトリアージスキルです。セキュリティ担当者や開発チームが検出結果を検証し、OWASP の方法でリスクを評価して修正の優先順位を決められます。
主な機能
- 01OWASP Top 10 による分類
- 02真陽性と誤検知の検証
- 03OWASP リスク評価の算出
- 04SQL インジェクションと XSS の手動テスト
- 05トリアージレポートの生成
活用シーン
- 01DAST と SAST のスキャン結果の確認
- 02Web 脆弱性修正の優先順位付け
- 03SQL インジェクションや XSS の疑いの検証
- 04追跡用の検出結果の整理
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill performing-web-application-vulnerability-triageインストール後、Claude Code で/performing-web-application-vulnerability-triageを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEreferences/api-reference.mdstandards.mdworkflows.mdscripts/agent.py詳細
Web アプリケーション脆弱性のトリアージ
概要
Web アプリケーション脆弱性のトリアージとは、DAST(動的アプリケーションセキュリティテスト)および SAST(静的アプリケーションセキュリティテスト)ツールの検出結果を確認し、真陽性を検証し、誤検知を除外し、OWASP リスク評価方法を用いてリスクを評価し、修正の優先順位を決めるプロセスです。効果的なトリアージにより、アラート疲れを軽減し、開発チームが最も重要な脆弱性に集中できるようになります。
使用する場面
- Web アプリケーション脆弱性のトリアージを実施するセキュリティ評価を行うとき
- 関連するセキュリティイベントのインシデント対応手順に従うとき
- 定期的なセキュリティテストや監査を実施するとき
- 実地テストを通じてセキュリティ制御を検証するとき
前提条件
- DAST スキャン結果(OWASP ZAP、Burp Suite、Acunetix)
- SAST スキャン結果(Semgrep、SonarQube、Checkmarx、Snyk Code)
requests、beautifulsoup4を含む Python 3.9 以降- 手動検証用の Burp Suite Professional または OWASP ZAP
- 検出結果の管理用の DefectDojo または同様のツール
OWASP リスク評価方法
リスクの計算
Risk = Likelihood x Impact
可能性の要因(0~9 の尺度)
| 要因グループ | 要因 | 説明 |
|---|---|---|
| 脅威エージェント | スキルレベル | 攻撃者の技術的なスキルはどの程度ですか? |
| 脅威エージェント | 動機 | 攻撃者の動機はどの程度強いですか? |
| 脅威エージェント | 機会 | どのようなリソースやアクセスが必要ですか? |
| 脅威エージェント | 規模 | 潜在的な脅威エージェントのグループはどの程度の規模ですか? |
| 脆弱性 | 発見の容易さ | 脆弱性を発見するのはどの程度容易ですか? |
| 脆弱性 | 悪用の容易さ | 悪用するのはどの程度容易ですか? |
| 脆弱性 | 認知度 | 脆弱性はどの程度広く知られていますか? |
| 脆弱性 | 侵入検知 | 悪用が検知される可能性はどの程度ですか? |
影響の要因(0~9 の尺度)
| 要因グループ | 要因 | 説明 |
|---|---|---|
| 技術 | 機密性 | どの程度のデータが漏えいする可能性がありますか? |
| 技術 | 完全性 | どの程度のデータが改ざんされる可能性がありますか? |
| 技術 | 可用性 | どの程度のサービスが利用できなくなる可能性がありますか? |
| 技術 | 説明責任 | 攻撃者に行為を結び付けて追跡できますか? |
| ビジネス | 金銭的損害 | 収益の損失、規制上の罰金 |
| ビジネス | 評判への損害 | ブランドへの信頼の低下 |
| ビジネス | コンプライアンス違反 | 規制違反にさらされる可能性 |
| ビジネス | プライバシー侵害 | 漏えいする PII/PHI の量 |
リスクマトリックス
| 影響:低(0~3) | 影響:中(3~6) | 影響:高(6~9) | |
|---|---|---|---|
| 可能性:高(6~9) | 中 | 高 | 重大 |
| 可能性:中(3~6) | 低 | 中 | 高 |
| 可能性:低(0~3) | 注記 | 低 | 中 |
トリアージのプロセス
ステップ 1:OWASP Top 10 に基づく分類
OWASP_TOP_10_2021 = {
"A01": "Broken Access Control",
"A02": "Cryptographic Failures",
"A03": "Injection",
"A04": "Insecure Design",
"A05": "Security Misconfiguration",
"A06": "Vulnerable and Outdated Components",
"A07": "Identification and Authentication Failures",
"A08": "Software and Data Integrity Failures",
"A09": "Security Logging and Monitoring Failures",
"A10": "Server-Side Request Forgery",
}
CWE_TO_OWASP = {
"CWE-79": "A03", # XSS -> Injection
"CWE-89": "A03", # SQL Injection
"CWE-78": "A03", # OS Command Injection
"CWE-352": "A01", # CSRF -> Access Control
"CWE-22": "A01", # Path Traversal
"CWE-200": "A02", # Information Exposure
"CWE-327": "A02", # Weak Cryptography
"CWE-287": "A07", # Authentication Issues
"CWE-918": "A10", # SSRF
"CWE-502": "A08", # Deserialization
"CWE-611": "A05", # XXE -> Misconfiguration
}
ステップ 2:真陽性と誤検知の検証
def triage_finding(finding):
"""Classify finding as true_positive, false_positive, or needs_review."""
fp_indicators = [
"Content-Security-Policy header not set", # Often informational
"X-Content-Type-Options header missing", # Low severity header
"Cookie without SameSite attribute", # Context dependent
]
for indicator in fp_indicators:
if indicator.lower() in finding.get("title", "").lower():
if finding.get("severity", "").lower() in ("info", "low"):
return "false_positive", "Common informational finding"
# Check for confirmed exploitation evidence
if finding.get("evidence") and finding.get("confidence", "").lower() == "certain":
return "true_positive", "Scanner confirmed exploitation"
# SAST findings need manual code review
if finding.get("source") == "sast":
if finding.get("cwe") in ["CWE-89", "CWE-78", "CWE-79"]:
return "needs_review", "Injection finding requires manual code review"
return "needs_review", "Requires manual validation"
ステップ 3:リスクスコアの計算
def calculate_risk_score(finding, app_context):
"""Calculate OWASP risk rating for a web application finding."""
# Likelihood factors
likelihood = {
"skill_level": 6 if finding["cwe"] in ["CWE-89", "CWE-79"] else 4,
"motive": 7, # Financial gain
"opportunity": 7 if finding.get("authenticated") == False else 4,
"size": 9 if finding.get("internet_facing") else 4,
"ease_of_discovery": 8 if finding.get("scanner_detected") else 5,
"ease_of_exploit": 7 if finding.get("exploit_available") else 4,
"awareness": 6,
"intrusion_detection": 3 if app_context.get("waf_enabled") else 8,
}
# Impact factors
impact = {
"confidentiality": 9 if "data_exposure" in finding.get("tags", []) else 5,
"integrity": 9 if finding["cwe"] in ["CWE-89", "CWE-78"] else 4,
"availability": 7 if "dos" in finding.get("tags", []) else 2,
"accountability": 3 if app_context.get("logging_enabled") else 7,
"financial": 7 if app_context.get("processes_payments") else 3,
"reputation": 6 if app_context.get("customer_facing") else 2,
"compliance": 8 if app_context.get("pci_scope") else 3,
"privacy": 9 if app_context.get("handles_pii") else 2,
}
likelihood_score = sum(likelihood.values()) / len(likelihood)
impact_score = sum(impact.values()) / len(impact)
risk_score = likelihood_score * impact_score
if risk_score >= 42:
risk_level = "Critical"
elif risk_score >= 24:
risk_level = "High"
elif risk_score >= 12:
risk_level = "Medium"
elif risk_score >= 3:
risk_level = "Low"
else:
risk_level = "Note"
return {
"likelihood_score": round(likelihood_score, 1),
"impact_score": round(impact_score, 1),
"risk_score": round(risk_score, 1),
"risk_level": risk_level,
}
ステップ 4:トリアージレポートの作成
# Process DAST/SAST results through triage pipeline
python3 scripts/process.py \
--input zap_results.json \
--format zap \
--app-context app_config.json \
--output triage_report.json
手動検証の手法
SQL インジェクションの検証
# Test parameter with single quote
GET /search?q=test' HTTP/1.1
# Test with boolean-based payload
GET /search?q=test' AND 1=1-- HTTP/1.1
GET /search?q=test' AND 1=2-- HTTP/1.1
# Time-based verification
GET /search?q=test'; WAITFOR DELAY '0:0:5'-- HTTP/1.1
XSS の検証
# Reflected XSS test
GET /search?q=<script>alert(document.domain)</script> HTTP/1.1
# Check if output is encoded
GET /search?q="><img src=x onerror=alert(1)> HTTP/1.1
# DOM-based XSS
GET /page#<img src=x onerror=alert(1)> HTTP/1.1
参考資料
コメント
Markdown 対応