Hi everyone,
I recently faced a challenge integrating Trivy scans with SonarQube (Community Edition), specifically regarding Docker image vulnerabilities. I noticed many users in this forum have struggled with this same issue, so I wanted to share the solution I developed.
The Problem: “Ghost” Vulnerabilities
When scanning a Docker image (e.g., debian:bookworm), Trivy finds vulnerabilities in system files like /usr/lib/libc.so or /bin/bash.
However, when importing the Trivy JSON report into SonarQube using the Generic Issue Import format, these vulnerabilities are silently ignored.
Why? Because SonarScanner only reports issues on files that exist in the Git repository’s index. Since /usr/lib/... exists only inside the built container and not in your source code, SonarQube discards them.
The Solution: Anchoring to Dockerfile
To fix this, I wrote a lightweight Python script (CI/CD ready) that converts the Trivy JSON report to the SonarQube Generic format using the following logic:
-
Smart Anchoring: It detects if a vulnerability belongs to an OS Package (Class:
os-pkgs). If so, it rewrites thefilePathto yourDockerfile(Line 1). This forces SonarQube to “see” the vulnerability and display it in the dashboard. -
Severity Enforcement: It maps Trivy’s
CRITICALseverity to SonarQube’sBLOCKER. This ensures that your Quality Gate fails if a critical vulnerability is found in the container, preventing insecure deployments. -
Correct Typing: It forces the issue type to
VULNERABILITY(instead of Code Smell), so it appears correctly in the Security tab.
Results
I went from a clean (false negative) dashboard to properly seeing all 60+ OS vulnerabilities.
1. Full visibility & correct severity Here you can see the Critical vulnerabilities correctly imported as “Blocker”:
2. Anchored to code The vulnerabilities are displayed in context, anchored to the first line of the Dockerfile:
The code
I’ve open-sourced the converter script and a complete GitLab CI/CD example (including fixes for Docker-in-Docker permission errors) here:
The script has zero dependencies (pure Python 3) and is optimized to pass SonarQube’s own cognitive complexity checks.
I hope this helps anyone trying to implement a robust DevSecOps pipeline with Trivy and SonarQube!

