Malware Package UI Representation and Filters
## TL;DR Enable users to identify and filter malicious packages across Dependency Lists, Vulnerability Reports, and Details pages as part of the SSCS add-on. ## Overview This epic delivers the UI layer for malicious package detection, building on top of the backend ingestion work in [&20538](https://gitlab.com/groups/gitlab-org/-/epics/20538). Once malware data flows through the GitLab SBOM Vulnerability Scanner, users need a way to visually identify, filter, and understand malicious packages in their projects. ## Business Value - **Security visibility:** Users can quickly identify malicious packages threatening their supply chain - **Efficient triage:** Dedicated filters help security teams focus on malware vs CVE vulnerabilities - **Appropriate context:** Details page shows relevant malware information without confusing CVE-specific fields - **Revenue enablement:** Feature gated behind SSCS add-on drives add-on adoption ## Scope ### In Scope **Dependency List** - Malware indicator badge (red "Malware" badge) - Rename "Vulnerabilities" column to "Risk" - Malware indicator in dependency list export - `malware` filter token **Vulnerability Report** - Malware package display with name, severity (Critical), identifier (CWE-506), report type - `malware` (Y/N) filter token - Under the hood: Filter by identifier (`CWE-506` or `GLAM`) - Existing findings **must be retained**, **must not** be auto-resolved or removed, and their status should be left unmodified _(“Needs Triage”, “Confirmed”,  “Dismissed” + reason, “Resolved” if a user takes an action to resolve it)_. Absence of updated detection of results reflects loss of scan capability, not remediation. **Vulnerability Details Page** - Display: Content from GLAD, affected packages, links, reachability, identifiers - Exclude: Solution field (legal liability), KEV, EPSS, CVSS **Security Dashboard** - Track each malware package instance as 1 vulnerability - Filter by report type support (Malware Packages should be a standalone report type - possibly implemented the same way as the vulnerability report feature) - Risk score calculation updates for malware - If the add on is removed, results from prior scans can remain aggregated in security dashboard until they are expired. **License Gating** - SSCS add-on entitlement checks - Empty states with upsell messaging ### Out of Scope - Filter for 'risk type' on dependency list (has vulns, is malware, none) - Changes to policies - Pipeline \> Security (findings) - MR Security Widget (findings) - Security Center changes ## Problem Statement The Composition Analysis team is implementing backend ingestion of malware advisories into PMDB (see [epic &20538](https://gitlab.com/groups/gitlab-org/-/epics/20538)). Once complete, malware data will flow through the GitLab SBOM Vulnerability Scanner and appear as vulnerabilities. Users currently have no way to: - Visually distinguish malware packages from CVE vulnerabilities - Filter to focus on malware findings - See appropriate details for malware (without irrelevant CVE fields) ## Proposed Approach **Phase 1: Display Malware Package Information** - Backend exposes `malware` fields in APIs - Frontend displays badges on Dependency Lists and Vulnerability Reports - Details page conditionally hides CVE-specific fields for malware - Export includes malware status **Phase 2: Malware Package Status Filters** - Backend adds filter parameters to finders/resolvers - Frontend adds filter tokens to Dependency Lists and Vulnerability Reports **Phase 3: Gate Malware Packages Behind SSCS Add-on** - Backend gates malware data behind SSCS add-on entitlement - Frontend shows empty states with upsell when not entitled **Phase 4: Integrate Malware Packages in Security Dashboard** (can run in parallel) - Update risk score calculation to include malware - Verify dashboard metrics include malware - Coordinate with VR team on weighting ## Feature Flags - [x] Required - [ ] **`malicious_package_badges`** - Phase 1 * **`malicious_package_filters`** - Phase 2 * **`malicious_package_license_gating`** - Phase 3 * **`malicious_package_risk_score`** - Phase 4 * **Default state:** Disabled * **Rollout plan:** Phase by phase Alternatively, we can also put everything behind one feature flag (simpler rollout). ## Success Criteria - [ ] Malware packages visually distinguishable via badges in Dependency Lists - [ ] Malware packages visually distinguishable via badges in Vulnerability Reports - [ ] Users can filter dependencies and vulnerabilities by malware status - [ ] Vulnerability Details page hides Solution/CVSS/EPSS/KEV for malware - [ ] Security Dashboard risk score includes malware - [ ] Feature gated behind SSCS add-on license - [ ] Works at project and group levels ## Timeline `/estimate TBD (BE estimates are pending)` ### Milestones | Phase | Scope | Estimate | |-------|-------|----------| | Phase 1 | Display Malware Package Information | TBD | | Phase 2 | Malware Package Status Filters | TBD | | Phase 3 | Gate Malware Packages Behind SSCS Add-on | TBD | | Phase 4 | Integrate Malware Packages in Security Dashboard | TBD (parallel) | ## Dependencies ### Upstream Dependencies | Dependency | Epic/Issue | Team | Status | |------------|------------|------|--------| | PMDB malware advisory ingestion | [&20538](https://gitlab.com/groups/gitlab-org/-/epics/20538) | Composition Analysis | In Progress | | Private malware advisory repo | TBD | Vulnerability Research | In Progress | | SBOM Scanner identifier generation | TBD (from &amp;20538 discussion) | Composition Analysis | Planning | | Dependency Management using ElasticSearch | #17619 | Security Infrastructure | Planning | ### Key Technical Context (from &amp;20538) **Identifier Format:** - Proposed format: `GLAM-` (see https://gitlab.com/gitlab-org/gitlab/-/work_items/588568#note_3084795090) **Data Flow:** ``` Private Malware Repo → PMDB Feeder → PMDB Exporter → Rails Sync → SBOM Scanner → Vulnerabilities ``` ## Child Epics & Issues ### [Display Malware Package Information](https://gitlab.com/groups/gitlab-org/-/epics/20572) ```glql display: table title: Display Malware Package Information fields: title, labels("backend", "frontend") AS "Type", status query: group = "gitlab-org" and type in (Issue, Task) and epic = gitlab-org&20572 ``` ### [Malware Package Status Filters](https://gitlab.com/groups/gitlab-org/-/epics/20573) ```glql display: table title: Display Malware Package Information fields: title, labels("backend", "frontend") AS "Type", status query: group = "gitlab-org" and type in (Issue, Task) and epic = gitlab-org&20573 ``` ### [Gate Malware Packages Behind SSCS Add-on](https://gitlab.com/groups/gitlab-org/-/epics/20574) ```glql display: table title: Display Malware Package Information fields: title, labels("backend", "frontend") AS "Type", status query: group = "gitlab-org" and type in (Issue, Task) and epic = gitlab-org&20574 ``` ### [Integrate Malware Packages in Security Dashboard](https://gitlab.com/groups/gitlab-org/-/epics/20575) ```glql display: table title: Display Malware Package Information fields: title, labels("backend", "frontend") AS "Type", status query: group = "gitlab-org" and type in (Issue, Task) and epic = gitlab-org&20575 ``` ## Open Questions See sub-epics for additional open questions: - [Gate Malware Packages Behind SSCS Add-on](https://gitlab.com/groups/gitlab-org/-/epics/20574) - License gating & expiry behavior - [Integrate Malware Packages in Security Dashboard](https://gitlab.com/groups/gitlab-org/-/epics/20575) - Risk score weighting ## Decision Log | Date | Decision | Rationale | Owner | |------|----------|-----------|-------| | 2026-02-16 | Internal Identifier decision (`GLAM`) | distinction from other identifiers | | | 2026-01-20 | Standalone `malware` filter token (not integrated with existing filters) | Malware triage is a distinct workflow from CVE triage | `@mclausen35` | | 2026-01-20 | Malware stays under "Dependency Scanning" report type (no new report type) | Simpler implementation, malware is subset of DS findings | `@mclausen35` | | 2026-01-20 | Hide malware records entirely when user lacks add-on | Clean UX, no partial data exposure | `@mclausen35` | | 2025-07-11 | Exclude Solution field for malware (legal liability) | Cannot advise remediation for malware | `@johncrowley` | | 2025-07-11 | Exclude KEV, EPSS, CVSS for malware | Not applicable to malware findings | `@johncrowley` | | 2025-07-11 | Rename "Vulnerabilities" column to "Risk" | Encompasses both CVEs and malware | `@johncrowley` | | 2026-23-02 | Keep and show existing data even after add-on-expiry (plus filter functionality) | | `@mclausen35` | ## Resources - **Upstream epic:** [&20538 - Ingest malware advisories in PMDB](https://gitlab.com/groups/gitlab-org/-/epics/20538) - Design issue: https://gitlab.com/gitlab-org/gitlab/-/issues/551225 - Technical spike: https://gitlab.com/gitlab-org/gitlab/-/issues/583911 - Risk score issue: https://gitlab.com/gitlab-org/gitlab/-/issues/551239#note_2620976437 --- <details> <summary> Original Epic Description (created by \`@mclausen35\`) </summary> ## Executive Summary All Executive Summary data is stored in the parent epic. #### Engineering Assessment #### Dependencies * _Dependency for_ https://gitlab.com/gitlab-org/gitlab/-/issues/551225+ # In Scope * These capabilities should only be available for orgs that have purchased the SSCM add-on. This ultimately means that the malicious package information should not be ingested (as everything else is downstream from that) **On the dependency list** * Malware indicator: We should possibly rename the vulnerability column to 'risks' and potentially include license risks in this too, in the future. * The malware indicator should be present in the export of the dependency list * The 'is malware' feature should be present on this page as well. **On the vulnerability Report** The malicious package should be rendered like this * Name: Malicious package 'package name' detected, introducing CWE-xyz (from the GLAD repo) * Severity: Collected pre-Sec. Insights, always Critical * Identifier: CWE type **(always CWE-506)** * **This will enable filtering as well** * Report type: dependency scanning * Filters * Filtering can be applied via identifier (CWE-506 or MAL-XXXX) * The filter should state 'isMalware (Y/N) and on the backend refer back to the CWE-506 value or the MAL- prefix. * Vuln details * Content in GLAD * Affected packages * Links: GLAD advisory, details on affecting CWE type * Solution: Exclude solution per the below * **Referencing at** [**GitHub advisory**](https://github.com/advisories/GHSA-778j-3w56-g989) **for Malware they do not provide a solution. I think we should not propose a solution because we are telling the user what to do when we are making an assumption. With a CVE the solution is provided to us and we just consume that data from GitHub / NVD. I think instructing the user to perform an action would potentially open us up to legal liability.** * Exclude: KEV, EPSS, and CVSS * Include: Reachability * Identifiers (from GLAD) * **CWE** * **GitHub unique ID** * **Internal ID (MAL-XXX)** * **Any other links provided by GLAD, which is how we operate with CVE vulnerabilities.** **On the dashboard** * Track each instance of a 'malicious package' as 1 vulnerability (IE is imported transiitvely or directly via a pom file in a project) * Filter by report type support * Risk score update support required from VR team. * https://gitlab.com/gitlab-org/gitlab/-/issues/551239#note_2620976437 # Out of Scope * Filter for 'risk type' on the dependenct list (has vulns, is malware, none) * Changes to policies * New data and new filters on the vulnerability report ## Functional Requirements ### Page Level Support * [x] Project * [x] Group * [ ] Pipeline \> Security (findings) * [ ] MR Security Widget (findings) * [ ] Security Center * [x] Security Dashboard * [x] Dependency List ### Workflow * [ ] Requires an additional filter on the Vulnerability Report ([docs](https://docs.gitlab.com/development/internal_analytics/internal_event_instrumentation/quick_start/)) * [ ] Requires an addition to the Vulnerability Report export ([docs](https://docs.gitlab.com/user/application_security/vulnerability_report/#exporting)) * [ ] Requires an additional filter on the Dependency List ([docs](https://docs.gitlab.com/user/application_security/dependency_list/)) * [x] Requires an addition to the Dependency List export ([docs](https://docs.gitlab.com/user/application_security/dependency_list/#export)) * [ ] Requires ~documentation ## Non-Functional Requirements ### Product Usage * [x] Requires new instrumentation ([docs](https://docs.gitlab.com/development/internal_analytics/internal_event_instrumentation/quick_start/)) ### Feature Flag Usage * [x] This feature should be released behind a feature flag? ([docs](https://handbook.gitlab.com/handbook/product-development/product-development-flow/feature-flag-lifecycle/#when-to-use-feature-flags)) ### Testing * [ ] Requires new E2E test coverage ([docs](https://docs.gitlab.com/development/testing_guide/end_to_end/)) * [ ] Requires extended manual / UAT phase * [ ] Performance testing needed ([testing](https://docs.gitlab.com/ci/testing/load_performance_testing/)) ## Outstanding Questions tbd ## Designs tbd </details>
epic