mcpField
P
performing-web-application-vulnerability-triage

performing-web-application-vulnerability-triage

github.com/mukul975安全35.2k446 次安装8 周前更新
代码仓库

关于 performing-web-application-vulnerability-triage

用于审查 DAST 和 SAST 扫描结果的 Web 应用安全分流技能。帮助安全与开发团队验证告警,依据 OWASP 方法评估风险,并确定修复优先级。

主要功能

  1. 01按 OWASP Top 10 分类发现项
  2. 02验证真实与误报
  3. 03计算 OWASP 风险评级
  4. 04手动测试 SQL 注入与 XSS
  5. 05生成分流报告

适用场景

  1. 01审查 DAST 和 SAST 扫描结果
  2. 02确定 Web 漏洞修复优先级
  3. 03验证疑似 SQL 注入或 XSS
  4. 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 外,安装时一起下载的参考资料和脚本。

LICENSE
references/
api-reference.md
standards.md
workflows.md
scripts/
agent.py

详细介绍

Web 应用程序漏洞分诊

概述

Web 应用程序漏洞分诊是指审查 DAST(动态应用程序安全测试)和 SAST(静态应用程序安全测试)工具的发现结果,以验证真实阳性、驳回误报、使用 OWASP 风险评级方法分配风险等级,并确定修复优先级。有效的分诊可以减少告警疲劳,让开发团队专注于最重要的漏洞。

适用场景

  • 开展涉及 Web 应用程序漏洞分诊的安全评估时
  • 遵循相关安全事件的事件响应流程时
  • 开展定期安全测试或审计活动时
  • 通过动手测试验证安全控制时

前置条件

  • DAST 扫描结果(OWASP ZAP、Burp Suite、Acunetix)
  • SAST 扫描结果(Semgrep、SonarQube、Checkmarx、Snyk Code)
  • Python 3.9+ 和 requests、beautifulsoup4
  • 用于手动验证的 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