BE: Add support for EPSS filter in MRAP policy

Summary

Add backend support for EPSS (Exploit Prediction Scoring System) score filtering in Merge Request Approval Policies. This will allow policy creators to define approval rules based on the likelihood of vulnerability exploitation, enabling more nuanced risk-based security policies.

Background

EPSS scores (ranging from 0 to 1) indicate the probability that a vulnerability will be exploited in the wild within the next 30 days. By incorporating EPSS filtering into MR approval policies, AppSec teams can:

  • Increase sensitivity for high-EPSS vulnerabilities that pose immediate risk
  • Reduce noise by allowing lower-EPSS vulnerabilities to proceed without blocking
  • Combine with severity levels for sophisticated risk-based policies (e.g., block High severity vulnerabilities only if EPSS > 0.5)

EPSS data is already available in the pm_cve_enrichment table and is updated hourly. This issue focuses on making that data actionable within MR approval policy evaluation.

Related Work

Proposal

Policy YAML Schema Extension

Extend the vulnerability_attributes section to support EPSS score filtering:

approval_rules:
  - name: High EPSS score vulnerabilities require approval
    approvals_required: 2
    user_approvers:
      - security-team-lead
    applies_to_all_protected_branches: true
    security_orchestration_policy:
      type: scan_finding
      branches:
        - main
      scanners:
        - dependency_scanning
        - container_scanning
      vulnerabilities:
        - vulnerability_attributes:
            epss_score:
              operator: greater_than
              value: 0.75
              missing_epss_fallback: 0.0  # Optional: default value when EPSS data is missing
          actions:
            - type: require_approval

Supported Operators

  1. greater_than: Block if EPSS score > specified value
  2. less_than: Block if EPSS score < specified value
  3. between: Block if EPSS score is within range (requires min and max values)

Example with between:

vulnerability_attributes:
  epss_score:
    operator: between
    min: 0.3
    max: 0.8
    missing_epss_fallback: 0.0

Combined Policy Example

approval_rules:
  - name: Combined severity and EPSS policy
    approvals_required: 2
    security_orchestration_policy:
      type: scan_finding
      scanners:
        - dependency_scanning
        - container_scanning
      vulnerabilities:
        - severity:
            - Critical
            - High
          vulnerability_attributes:
            epss_score:
              operator: greater_than
              value: 0.5
              missing_epss_fallback: 0.0

Implementation Requirements

1. Schema Validation

  • Extend policy schema to accept epss_score within vulnerability_attributes
  • Validate operator field (must be one of: greater_than, less_than, between)
  • Validate value field (must be decimal between 0.0 and 1.0)
  • For between operator: validate min and max fields (both required, min < max)
  • Validate optional missing_epss_fallback field (decimal between 0.0 and 1.0)
  • Add appropriate error messages for invalid configurations

2. Policy Evaluation Logic

  • Implement EPSS score filtering in MR approval policy evaluation
  • Join security findings with pm_cve_enrichment table using CVE identifiers
  • Extract EPSS scores for all CVEs associated with a finding
  • When multiple CVEs exist for a single vulnerability: Use the highest EPSS score for policy evaluation
  • Apply operator logic (greater_than, less_than, between) to determine policy violations
  • Handle findings without CVEs: exclude from EPSS filtering (only applies to DS/CS findings with CVEs)

3. Missing EPSS Data Handling (workflowneeds clarification)

  • When EPSS data is missing for a CVE:
    • If missing_epss_fallback is specified in policy: use that value
    • If missing_epss_fallback is NOT specified: [PM to clarify default behavior]
      • Option A: Treat as 0.0 (no exploitation risk)
      • Option B: Treat as 1.0 (maximum risk - fail-safe approach)
      • Option C: Exclude from policy evaluation entirely
      • Option D: Mark as "unknown" and require explicit policy configuration
  • Document the chosen behavior clearly in policy documentation

4. API Extensions

  • Extend GraphQL/REST APIs to expose EPSS scores in policy violation responses
  • Include EPSS score in security finding details when policy violations occur
  • Ensure APIs return EPSS data for MR security reports

5. Bot Comment Updates

  • Update MR approval bot comments to include EPSS-related violation details
  • Example: "3 vulnerabilities with EPSS score > 0.75 found: CVE-2024-1234 (EPSS: 0.89), CVE-2024-5678 (EPSS: 0.82), CVE-2024-9012 (EPSS: 0.76)"
  • Include information about missing EPSS data if applicable
  • Add disclaimer about EPSS scores being snapshot at scan time

6. Performance Optimization

  • Optimize database queries for joining findings with pm_cve_enrichment
  • Add database indexes if needed (coordinate with Database team)
  • Test performance with large vulnerability datasets (100+ findings per MR)
  • Ensure query performance doesn't degrade MR approval checks

7. Testing

  • Unit tests for EPSS score filtering logic (all operators)
  • Unit tests for multiple CVEs per vulnerability (highest score selection)
  • Unit tests for missing EPSS data handling
  • Integration tests with real policy YAML configurations
  • Integration tests combining EPSS with severity filters
  • Edge case tests:
    • Vulnerabilities without CVEs (should be excluded)
    • Invalid CVE formats
    • EPSS scores at boundaries (0.0, 1.0)
    • Empty/null EPSS values
  • Performance tests with high-volume datasets

Technical Implementation Notes

Data Flow

flowchart TD
    subgraph Database
        pm_cve_enrichment[pm_cve_enrichment Table]
        pm_cve_enrichment --> |contains| cve_column[cve column]
        pm_cve_enrichment --> |contains| epss_column[epss_score column]
    end

    subgraph MR_Approval_Process
        mr[Merge Request]
        policy_check[MR Approval Policy Check]
        extract_cve[Extract CVE Identifiers]
        lookup_epss[Lookup EPSS Scores]
        select_highest[Select Highest EPSS if Multiple CVEs]
        apply_fallback[Apply Fallback if Missing]
        evaluate[Evaluate Against Policy Rules]
        decision[Approval Decision]
    end

    mr --> policy_check
    policy_check --> extract_cve
    extract_cve --> lookup_epss
    lookup_epss --> |query| epss_column
    cve_column --> |match with| extract_cve
    epss_column --> select_highest
    select_highest --> apply_fallback
    apply_fallback --> evaluate
    evaluate --> decision
    decision --> |requires approval?| mr

Key Considerations

  1. Scope: EPSS filtering only applies to Dependency Scanning and Container Scanning findings that have associated CVEs
  2. EPSS Score Updates: Scores are evaluated at scan time (snapshot). If EPSS scores change after scan, they won't affect existing MR policy evaluations until pipeline re-runs
  3. No Feature Flag Required: When epss_score filter is not present in policy YAML, no EPSS evaluation occurs
  4. Consistency with KEV Implementation: Follow similar patterns established in KEV filter implementation (#576858 (closed), #576859, #576860 (closed), #576862 (closed), #577315 (closed))

Edge Cases & Decisions

Scenario Decision
Multiple CVEs per vulnerability Use highest EPSS score
Vulnerability without CVE Exclude from EPSS filtering
Missing EPSS data in pm_cve_enrichment Use missing_epss_fallback if specified; otherwise [PM to clarify]
SAST/Secret Detection findings Not applicable (no CVEs)
Invalid CVE format Treat as missing EPSS data
EPSS score changes after scan Use snapshot at scan time; re-evaluate on pipeline re-run

Acceptance Criteria

  • Policy YAML schema supports epss_score filtering with all three operators (greater_than, less_than, between)
  • Policy evaluation correctly filters vulnerabilities based on EPSS scores
  • Multiple CVEs per vulnerability are handled correctly (highest score used)
  • Missing EPSS data is handled according to PM-defined behavior
  • Bot comments clearly communicate EPSS-related policy violations
  • APIs expose EPSS scores in policy violation responses
  • Performance is acceptable for large vulnerability datasets (< 2s for 100+ findings)
  • All tests pass (unit, integration, edge cases, performance)
  • Documentation is updated with EPSS filter usage examples

Documentation Requirements

  • Update MR Approval Policy documentation with EPSS filter examples
  • Document all supported operators and their behavior
  • Document missing_epss_fallback configuration option
  • Document edge cases (multiple CVEs, missing data, non-CVE findings)
  • Add examples of combined severity + EPSS policies
  • Document EPSS score snapshot behavior (evaluated at scan time)

Labels

groupsecurity policies Category:Security Policy Management devopssecurity risk management sectionsec security policymerge request approval policy typefeature backend workflowneeds clarification

Weight

TBD - To be estimated by engineering team

Milestone

%18.6


Related Epics:

  • &16575 (EPSS filter - parent epic)
  • &16311 (KEV filter - sibling implementation)

Related Issues:

Edited by 🤖 GitLab Bot 🤖