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
andReportConverter::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 totrue
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
- Replaced direct scan method calls with a unified
-
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:
-
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 returnEOSL
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 includeEOL
status through the current template mechanism. -
Create separate reports and merge them: This would generate separate reports for
EOL
andCS
, then use aReportMerger
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
For example, see https://gitlab.com/onaaman/eol-test/-/security/vulnerability_report:
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?
- Changelog entry added
- Documentation created/updated for GitLab EE, if necessary
- Documentation created/updated for this project, if necessary
- Documentation reviewed by technical writer or follow-up review issue created
- Tests added
- Job definition updated, if necessary
- Conforms to the code review guidelines
- Conforms to the Go guidelines
- Conforms to the Ruby guidelines
- Security reports checked/validated by reviewer