Skip to content

Detect & report End of Life operating systems

What does this MR do?

This MR introduces detection and reporting of end-of-life (EOL) operating systems in container scanning, identifying containers using OS versions no longer receiving security updates.

Changes

  • Added EOL detection using the Trivy scanner's EOSL metadata.

  • Introduces a new Plugin::Eol and ReportConverter::Eol to detect EOL OS, and append EOL vulnerabilities to the existing container scanning report.

    • The EOL vulnerability uses the same format as the existing CS vulnerabilities, so no monolith changes are required.
    • Uses a simple Trivy command to detect EOL status: trivy image --format json --output output_file image_name
  • Created configuration options:

    • CS_REPORT_OS_EOL: Enable/disable EOL detection (default: false, will be changed to true in the future).
    • CS_REPORT_OS_EOL_SEVERITY: Set severity level (default: Medium).
  • Refactored scanner.rb interface to reduce coupling:

    • Replaced direct scan method calls with a unified dispatch.
    • Added scan type constants (SCAN_TYPE_VULNERABILITY, SCAN_TYPE_SBOM, SCAN_TYPE_EOL)
    • Moved scan implementation from base Scanner class to concrete Trivy implementations
    • Updated tests accordingly
  • Added append functionality to vulnerability reports (utils.rb)

Implementation Details

EOL detection uses a simple Trivy command that checks the OS metadata for EOSL status. When detected, it adds an EOL vulnerability to the existing container scanning report.

Although Trivy uses the term EOSL, I've chosen EOL for consistency with standard terminology (e.g., endoflife.date).


Examples of running the Trivy Command:
1. Unsupported OS

% trivy image --format json --output trivy.json alpine:3.13 

2025-05-08T19:45:22+03:00	INFO	[vuln] Vulnerability scanning is enabled
2025-05-08T19:45:22+03:00	INFO	[secret] Secret scanning is enabled
2025-05-08T19:45:22+03:00	INFO	[secret] If your scanning is slow, please try '--scanners vuln' to disable secret scanning
2025-05-08T19:45:22+03:00	INFO	[secret] Please see also https://aquasecurity.github.io/trivy/v0.58/docs/scanner/secret#recommendation for faster secret detection
2025-05-08T19:45:23+03:00	INFO	Detected OS	family="alpine" version="3.13.12"
2025-05-08T19:45:23+03:00	INFO	[alpine] Detecting vulnerabilities...	os_version="3.13" repository="3.13" pkg_num=14
2025-05-08T19:45:23+03:00	INFO	Number of language-specific files	num=0
2025-05-08T19:45:23+03:00	WARN	This OS version is no longer supported by the distribution	family="alpine" version="3.13.12"
2025-05-08T19:45:23+03:00	WARN	The vulnerability detection may be insufficient because security updates are not provided
% cat trivy.json
{
  "SchemaVersion": 2,
  "CreatedAt": "2025-05-08T19:45:23.670725+03:00",
  "ArtifactName": "alpine:3.13",
  "ArtifactType": "container_image",
  "Metadata": {
    "OS": {
      "Family": "alpine",
      "Name": "3.13.12",
      "EOSL": true # <-- WE USE THIS
    },
    "ImageID": "sha256:6b5c5e00213a401b500630fd8a03f6964f033ef0e3a6845c83e780fcd5deda5c",
    "DiffIDs": [
      "sha256:7df5bd7bd26203cecd71c9f1a6e04ddf8a22a4440f2388a13c86f87f40d2d992"
    ],
   ...

2. Supported OS

% trivy image --format json --output trivy.json alpine:latest
2025-05-08T19:45:59+03:00	INFO	[vuln] Vulnerability scanning is enabled
2025-05-08T19:45:59+03:00	INFO	[secret] Secret scanning is enabled
2025-05-08T19:45:59+03:00	INFO	[secret] If your scanning is slow, please try '--scanners vuln' to disable secret scanning
2025-05-08T19:45:59+03:00	INFO	[secret] Please see also https://aquasecurity.github.io/trivy/v0.58/docs/scanner/secret#recommendation for faster secret detection
2025-05-08T19:46:01+03:00	INFO	Detected OS	family="alpine" version="3.21.3"
2025-05-08T19:46:01+03:00	WARN	This OS version is not on the EOL list	family="alpine" version="3.21"
2025-05-08T19:46:01+03:00	INFO	[alpine] Detecting vulnerabilities...	os_version="3.21" repository="3.21" pkg_num=15
2025-05-08T19:46:01+03:00	INFO	Number of language-specific files	num=0
[19:46] orin eosl_Tests  % cat trivy.json
{
  "SchemaVersion": 2,
  "CreatedAt": "2025-05-08T19:46:01.675463+03:00",
  "ArtifactName": "alpine:latest",
  "ArtifactType": "container_image",
  "Metadata": {
    "OS": {
      "Family": "alpine",
      "Name": "3.21.3" # <-- NO EOSL ENTRY
    },
    "ImageID": "sha256:aded1e1a5b3705116fa0a92ba074a5e0b0031647d9c315983ccba2ee5428ec8b",
    "DiffIDs": [
      "sha256:08000c18d16dadf9553d747a58cf44023423a9ab010aab96cf263d2216b8b350"
    ],
    ...

Prerequisites

Since we don't create a separate report and to align with the existing flow, there is a prerequisite that the container scanning must run first, otherwise the OS vulnerability won't be generated. The EoslScan plugin is placed last in the execution chain to ensure it appends to the existing report.

Alternatives considered

I considered 2 alternatives:

  1. Modify the existing container scan command: Instead of creating a separate Trivy command, I could update the existing one to fetch EOL data as well. The problem is that the current CS command uses a Trivy template that doesn't return EOSL information. Having a single Trivy command would require abandoning the template entirely and processing a raw JSON output, which I wanted to avoid. The template only fetches vulnerability data, not OS metadata, making it impossible to include EOL status through the current template mechanism.

  2. Create separate reports and merge them: This would generate separate reports for EOL and CS, then use a ReportMerger to combine them. While technically possible, this approach would add unnecessary complexity.

After evaluating these options, I chose to create a separate EOL plugin that appends to our existing container scanning reports. This approach:

  • Keeps our code structure clean while leveraging the new append feature
  • Maintains a single unified report
  • Preserves existing abstractions
  • Doesn't disrupt the main scanning flow
  • Follows the single responsibility principle by keeping EOL detection separate
  • Offers the most practical path to implementation with minimal disruption

Verification

vuln on vulnerability report

vuln in vulnerability details view

For example, see https://gitlab.com/onaaman/eol-test/-/security/vulnerability_report: image

What are the relevant issue numbers / merge requests ?

Container Scanning - Report vulnerability on un... (gitlab-org/gitlab#495640 - closed) • Orin Naaman • 18.2 • Needs attention Detect & report End of Life operating systems (!3191 - merged) • Orin Naaman • 18.1

Does this MR meet the acceptance criteria?

Edited by Orin Naaman

Merge request reports

Loading