The most surprising thing about Trivy’s "false positives" is that they often aren’t false at all, but rather an accurate reflection of vulnerabilities that your specific environment might not be exposed to, or that have mitigations in place which Trivy can’t automatically detect.

Let’s see Trivy in action scanning a container image for vulnerabilities.

# Scan a common image for OS package vulnerabilities
trivy image alpine:latest

# Scan for IaC misconfigurations
trivy config /path/to/your/terraform/code

# Scan for secrets
trivy fs --secret-config /path/to/your/secrets.yaml /path/to/your/codebase

Trivy works by maintaining a comprehensive database of known vulnerabilities (CVEs) and misconfigurations, mapping them to specific software packages, versions, and configuration patterns. When you scan an artifact (like a container image, filesystem, or IaC code), Trivy enumerates the components within it and cross-references them against its database. If a match is found, it flags it as a potential vulnerability or misconfiguration.

The "false positive" problem arises when Trivy flags something that, in your context, isn’t actually a risk. This could be because:

  • The vulnerability is mitigated by compensating controls: You might have network segmentation, WAF rules, or runtime security measures that prevent an attacker from exploiting a specific vulnerability. Trivy, by default, doesn’t know about these external controls.
  • The vulnerable component is not actually reachable or executable: A library might be present in an image but never loaded or used by the application.
  • The vulnerability is in a transitive dependency that’s not actively used: Similar to the above, a dependency of a dependency might have a CVE, but if the direct dependency doesn’t expose it, it might be considered a false positive.
  • The CVE has been superseded or is no longer considered exploitable: Sometimes, CVEs are updated, or new research shows they are harder to exploit than initially thought. Trivy’s database might lag slightly or include older, less critical assessments.
  • Misinterpretation of configuration or package versions: While rare, there can be edge cases where Trivy misinterprets a version string or a configuration directive.

To tune Trivy and reduce these perceived false positives, you can leverage its configuration and filtering capabilities.

1. Ignore Specific Vulnerabilities:

The most direct way to suppress known false positives is to tell Trivy to ignore them. You can create an ignore configuration file.

  • Diagnosis: Identify the exact vulnerability ID (e.g., CVE-2023-12345) from the Trivy output.

  • Fix: Create a file (e.g., trivy-ignore.yaml) with the following content:

    # trivy-ignore.yaml
    ignore:
      - RUL-001 # Example: Ignore a specific misconfiguration rule
      - CVE-2023-12345 # Example: Ignore a specific CVE
      - VS-001 # Example: Ignore a specific custom rule
    

    To ignore vulnerabilities within a specific package, you can use:

    ignore:
      - TARGET: "nginx:1.21.0" # Target specific package and version
        REASON: "Vulnerability is mitigated by WAF rules."
        CODE: "CVE-2023-98765"
    
  • Command: Run Trivy with the --ignore-policy flag:

    trivy image --ignore-policy trivy-ignore.yaml my-app:latest
    
  • Why it works: This explicitly instructs Trivy to skip reporting on the specified vulnerabilities or rules, effectively filtering them out of the results.

2. Filter by Severity:

Often, lower-severity vulnerabilities might not be a priority for your team. You can filter them out directly.

  • Diagnosis: Observe the Severity column in Trivy’s output (e.g., UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL).

  • Fix: Use the --severity flag to include only vulnerabilities above a certain threshold. For example, to only see HIGH and CRITICAL issues:

    trivy image --severity HIGH,CRITICAL my-app:latest
    
  • Why it works: This tells Trivy to only process and report on findings that meet or exceed the specified severity level, reducing noise from less critical issues.

3. Specify Target Packages and Applications (for OS Packages & Application Dependencies):

If you know a vulnerability exists in a package that your application doesn’t actually use or load, you can sometimes tell Trivy to focus its scanning. This is more advanced and might involve custom scripting or more in-depth analysis of your application’s runtime. For OS packages and application dependencies (like pip, npm, etc.), Trivy maps CVEs to specific package names and versions. If a package is present but not executed, it’s still flagged.

  • Diagnosis: You’ve identified a CVE for openssl but your application only uses curl.

  • Fix: While Trivy doesn’t have a direct "don’t scan this package" flag for arbitrary packages within an image scan, the ignore policy can be targeted by package name and version. More effectively, ensure your build process minimizes the attack surface. If a package is truly unused, it should be removed from the image.

    ignore:
      - TARGET: "openssl:1.1.1k-*" # Target a specific package and version pattern
        REASON: "Package is not used by the application."
        CODE: "CVE-2021-3711"
    

    Run with:

    trivy image --ignore-policy trivy-ignore.yaml my-app:latest
    
  • Why it works: By targeting the specific package and version, you’re telling Trivy to suppress findings related to it, assuming you’ve verified its non-usage. The best fix is always to remove unused software from your images.

4. Using Custom Rules (for IaC and Misconfigurations):

For Infrastructure as Code (IaC) and configuration scanning, Trivy allows custom rules. If Trivy flags a configuration that you’ve intentionally set for security or operational reasons, you can create a custom rule to accept that specific pattern.

  • Diagnosis: Trivy flags an S3 bucket that is intentionally public for a static website.

  • Fix: Write a custom rule that specifically allows this configuration.

    # custom-iac-rules.yaml
    custom:
      - id: ALLOWED-PUBLIC-S3-WEBSITE
        desc: "Allow public S3 buckets for static website hosting."
        impact: "Medium"
        severity: "MEDIUM"
        category: "IAM"
        rules:
          - "Resources[Type=AWS::S3::Bucket, Properties.AccessControlTranslation.Owner='Self'].Properties.PublicAccessBlockConfiguration.BlockPublicAcls = false"
          - "Resources[Type=AWS::S3::Bucket, Properties.AccessControlTranslation.Owner='Self'].Properties.PublicAccessBlockConfiguration.IgnorePublicAcls = false"
          - "Resources[Type=AWS::S3::Bucket, Properties.AccessControlTranslation.Owner='Self'].Properties.PublicAccessBlockConfiguration.RestrictPublicBuckets = false"
          - "Resources[Type=AWS::S3::Bucket, Properties.AccessControlTranslation.Owner='Self'].Properties.PublicAccessBlockConfiguration.BlockPublicPolicy = false"
          - "Resources[Type=AWS::S3::Bucket, Properties.BucketPublicAccess.Enable = true]"
    

    Run with:

    trivy config --custom-rules custom-iac-rules.yaml /path/to/tf/code
    
  • Why it works: Custom rules allow you to define exceptions or specific acceptable configurations, making Trivy’s output more relevant to your organization’s security posture.

5. Update Trivy and its Database Regularly:

Sometimes, what appears to be a false positive is simply an outdated assessment in the Trivy database.

  • Diagnosis: A CVE reported by Trivy is already marked as resolved or non-exploitable in official sources.

  • Fix: Ensure you are running the latest version of Trivy and that its vulnerability database is up-to-date.

    # Update Trivy executable (if installed via package manager)
    sudo apt-get update && sudo apt-get upgrade trivy # for Debian/Ubuntu
    # or
    brew upgrade trivy # for macOS with Homebrew
    
    # Trivy automatically fetches the latest database on each run,
    # but you can force an update if needed (rarely necessary)
    trivy image --download-db-only alpine:latest
    
  • Why it works: Newer versions of Trivy and its database incorporate the latest security research, CVE status updates, and corrections, which can resolve previously misclassified findings.

6. Contextualize Vulnerabilities:

This is less about tuning Trivy and more about understanding its output. Trivy provides CVE details, CVSS scores, and sometimes links to advisories. When you encounter a potential false positive, investigate the CVE itself. Does it require specific conditions to be exploitable? Is the vulnerable code path actually exercised in your application? This investigative step is crucial before dismissing a finding.

The next challenge you’ll likely face after tuning for false positives is managing the sheer volume of findings, even after filtering, and integrating Trivy’s results into your CI/CD pipeline for automated remediation.

Want structured learning?

Take the full Trivy course →