L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Développement · SKILL.md

performing-web-application-vulnerability-triage

performing-web-application-vulnerability-triage

使用 OWASP 风险评级方法论对 DAST/SAST 扫描器的 Web 应用程序漏洞发现进行分类,区分真阳性和假阳性,并确定修复优先级。

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: performing-web-application-vulnerability-triage description: 使用 OWASP 风险评级方法论对 DAST/SAST 扫描器的 Web 应用程序漏洞发现进行分类,区分真阳性和假阳性,并确定修复优先级。 domain: cybersecurity subdomain: vulnerability-management tags: [web-application, vulnerability-triage, owasp, dast, sast, burp-suite, zap, false-positive, risk-rating] version: "1.0" author: mahipal license: Apache-2.0

执行 Web 应用程序漏洞分类

概述

Web 应用程序漏洞分类(Triage)是审查 DAST(动态应用安全测试)和 SAST(静态应用安全测试)工具发现的过程,用于验证真阳性、排除假阳性、使用 OWASP 风险评级方法论分配风险等级,并确定修复优先级。有效的分类减少告警疲劳,使开发团队专注于最重要的漏洞。

前置条件

  • DAST 扫描结果(OWASP ZAP、Burp Suite、Acunetix)
  • SAST 扫描结果(Semgrep、SonarQube、Checkmarx、Snyk Code)
  • Python 3.9+,安装 requests、beautifulsoup4
  • Burp Suite Professional 或 OWASP ZAP 用于手动验证
  • DefectDojo 或类似工具用于发现管理

OWASP 风险评级方法论

风险计算

风险 = 可能性 × 影响

可能性因素(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": "访问控制失效",
    "A02": "加密失败",
    "A03": "注入",
    "A04": "不安全设计",
    "A05": "安全配置错误",
    "A06": "脆弱和过时组件",
    "A07": "身份识别和认证失败",
    "A08": "软件和数据完整性失败",
    "A09": "安全日志记录和监控失败",
    "A10": "服务器端请求伪造(SSRF)",
}

CWE_TO_OWASP = {
    "CWE-79": "A03",   # XSS -> 注入
    "CWE-89": "A03",   # SQL 注入
    "CWE-78": "A03",   # OS 命令注入
    "CWE-352": "A01",  # CSRF -> 访问控制
    "CWE-22": "A01",   # 路径遍历
    "CWE-200": "A02",  # 信息泄露
    "CWE-327": "A02",  # 弱加密
    "CWE-287": "A07",  # 认证问题
    "CWE-918": "A10",  # SSRF
    "CWE-502": "A08",  # 反序列化
    "CWE-611": "A05",  # XXE -> 配置错误
}

步骤 2:验证真阳性与假阳性

def triage_finding(finding):
    """将发现分类为 true_positive、false_positive 或 needs_review。"""
    fp_indicators = [
        "Content-Security-Policy header not set",  # 通常为信息性
        "X-Content-Type-Options header missing",    # 低严重性标头
        "Cookie without SameSite attribute",        # 取决于上下文
    ]

    for indicator in fp_indicators:
        if indicator.lower() in finding.get("title", "").lower():
            if finding.get("severity", "").lower() in ("info", "low"):
                return "false_positive", "常见信息性发现"

    # 检查已确认的利用证据
    if finding.get("evidence") and finding.get("confidence", "").lower() == "certain":
        return "true_positive", "扫描器已确认利用"

    # SAST 发现需要手动代码审查
    if finding.get("source") == "sast":
        if finding.get("cwe") in ["CWE-89", "CWE-78", "CWE-79"]:
            return "needs_review", "注入发现需要手动代码审查"

    return "needs_review", "需要手动验证"

步骤 3:风险评分计算

def calculate_risk_score(finding, app_context):
    """计算 Web 应用程序发现的 OWASP 风险等级。"""
    # 可能性因素
    likelihood = {
        "skill_level": 6 if finding["cwe"] in ["CWE-89", "CWE-79"] else 4,
        "motive": 7,  # 经济利益
        "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 = {
        "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 = "严重"
    elif risk_score >= 24:
        risk_level = "高"
    elif risk_score >= 12:
        risk_level = "中"
    elif risk_score >= 3:
        risk_level = "低"
    else:
        risk_level = "注意"

    return {
        "likelihood_score": round(likelihood_score, 1),
        "impact_score": round(impact_score, 1),
        "risk_score": round(risk_score, 1),
        "risk_level": risk_level,
    }

步骤 4:生成分类报告

# 通过分类流程处理 DAST/SAST 结果
python3 scripts/process.py \
  --input zap_results.json \
  --format zap \
  --app-context app_config.json \
  --output triage_report.json

手动验证技术

SQL 注入验证

# 使用单引号测试参数
GET /search?q=test' HTTP/1.1

# 使用基于布尔的载荷测试
GET /search?q=test' AND 1=1-- HTTP/1.1
GET /search?q=test' AND 1=2-- HTTP/1.1

# 基于时间的验证
GET /search?q=test'; WAITFOR DELAY '0:0:5'-- HTTP/1.1

XSS 验证

# 反射型 XSS 测试
GET /search?q=<script>alert(document.domain)</script> HTTP/1.1

# 检查输出是否已编码
GET /search?q="><img src=x onerror=alert(1)> HTTP/1.1

# DOM 型 XSS
GET /page#<img src=x onerror=alert(1)> HTTP/1.1

参考资料

Skills enregistrées