Trivy: Version comparison broken on Rubygems with suffixed versions

Created on 3 Aug 2019  路  13Comments  路  Source: aquasecurity/trivy

Description

Some of my Gemfile.lock files contain multiple lines for a particular gem, with platform-specific suffixes for each platform. i.e.:

    ffi (1.9.25)
    ffi (1.9.25-java)
    ffi (1.9.25-x64-mingw32)
    ffi (1.9.25-x86-mingw32)

These suffixed versions seem to trip trivy up.

What did you expect to happen?

I expected the platform-specific-suffixed versions of ffi to be ignored, or for them to be considered equivalent to 1.9.25.

What happened instead?

trivy seems unable to compare versions like this, or considers them equivalent to 0, and reports vulnerabilities that are already fixed:

  - VulnerabilityID: CVE-2018-1000201
    PkgName: ffi
    InstalledVersion: 1.9.25-java
    FixedVersion: ">= 1.9.24"
...
  - VulnerabilityID: CVE-2018-1000201
    PkgName: ffi
    InstalledVersion: 1.9.25-x64-mingw32
    FixedVersion: ">= 1.9.24"
...
  - VulnerabilityID: CVE-2018-1000201
    PkgName: ffi
    InstalledVersion: 1.9.25-x86-mingw32
    FixedVersion: ">= 1.9.24"

Output of run with -debug:

(only including the bit relevant to the Gemfile involved, as the scan of the entire container I'm working with is very long)

2019-08-02T22:12:51.240Z    DEBUG   Detecting library vulnerabilities, path: data/dependency-graph-api/0f6bb6b3a2f0580eaec35227d486ba1804422504/Gemfile.lock
2019-08-02T22:12:51.240Z    INFO    Updating bundler Security DB...
2019-08-02T22:12:51.240Z    DEBUG   git pull
2019-08-02T22:12:51.837Z    INFO    Detecting bundler vulnerabilities...
2019-08-02T22:12:51.837Z    DEBUG   Malformed version: 6.0.0.rc1
2019-08-02T22:12:51.837Z    DEBUG   Malformed version: 6.0.0.rc1
2019-08-02T22:12:51.837Z    DEBUG   Malformed version: 6.0.0.rc1
2019-08-02T22:12:51.837Z    DEBUG   Malformed version: 6.0.0.rc1
2019-08-02T22:12:51.837Z    DEBUG   Malformed version: 6.0.0.rc1
2019-08-02T22:12:51.837Z    DEBUG   Malformed version: 6.0.0.rc1
2019-08-02T22:12:51.837Z    DEBUG   Malformed version: 6.0.0.rc1
2019-08-02T22:12:51.837Z    DEBUG   Malformed version: 6.0.0.rc1
2019-08-02T22:12:51.837Z    DEBUG   Malformed version: 6.0.0.rc1
2019-08-02T22:12:51.837Z    DEBUG   Malformed version: 6.0.0.rc1
2019-08-02T22:12:51.837Z    DEBUG   Malformed version: 6.0.0.rc1
2019-08-02T22:12:51.837Z    DEBUG   Malformed version: 2.0.0.beta.1
2019-08-02T22:12:51.837Z    DEBUG   Malformed version: 0.1.0.g787a01c
2019-08-02T22:12:51.837Z    DEBUG   Malformed version: 0.2.0.ge32f911
2019-08-02T22:12:51.839Z    DEBUG   Malformed version: 6.0.0.rc1
2019-08-02T22:12:51.839Z    DEBUG   Malformed version: 6.0.0.rc1

Output of trivy -v:

trivy version 0.1.4
kinbug

All 13 comments

@jordemort Thank you for reporting this bug. Would you provide your Gemfile.lock? If it is difficult to provide the entire file, you can remove unrelated lines.

Experiencing this same issue with building FROM the logstash image. Logstash's Gem dependencies often have the "-java" suffix and this causes the behavior detailed in this issue. This is logstash's Gemfile.lock, where you can see dependencies with the "-java" suffix:

root@261340930a5f:/logstash# cat Gemfile.lock
PATH
  remote: logstash-core-plugin-api
  specs:
    logstash-core-plugin-api (2.1.16-java)
      logstash-core (= 8.0.0.SNAPSHOT)

PATH
  remote: logstash-core
  specs:
    logstash-core (8.0.0.SNAPSHOT-java)
      chronic_duration (~> 0.10)
      clamp (~> 0.6)
      concurrent-ruby (~> 1)
      elasticsearch (~> 5)
      filesize (~> 0.2)
      gems (~> 1)
      i18n (~> 1)
      jrjackson (= 0.4.9)
      jruby-openssl (~> 0.10)
      manticore (~> 0.6)
      minitar (~> 0.8)
      pry (~> 0.12)
      puma (~> 2)
      rack (~> 1, >= 1.6.11)
      rubyzip (~> 1)
      sinatra (~> 1, >= 1.4.6)
      stud (~> 0.0.19)
      thread_safe (~> 0.3.6)
      treetop (~> 1)

GEM
  remote: https://rubygems.org/
  specs:
    addressable (2.7.0)
      public_suffix (>= 2.0.2, < 5.0)
    arr-pm (0.0.10)
      cabin (> 0)
    atomic (1.1.101-java)
    backports (3.15.0)
    belzebuth (0.2.3)
      childprocess
    benchmark-ips (2.7.2)
    builder (3.2.3)
    cabin (0.9.0)
    childprocess (0.9.0)
      ffi (~> 1.0, >= 1.0.11)
    chronic_duration (0.10.6)
      numerizer (~> 0.1.1)
    ci_reporter (2.0.0)
      builder (>= 2.1.2)
    ci_reporter_rspec (1.0.0)
      ci_reporter (~> 2.0)
      rspec (>= 2.14, < 4)
    clamp (0.6.5)
    coderay (1.1.2)
    concurrent-ruby (1.1.5)
    crack (0.4.3)
      safe_yaml (~> 1.0.0)
    diff-lcs (1.3)
    dotenv (2.7.5)
    elasticsearch (5.0.5)
      elasticsearch-api (= 5.0.5)
      elasticsearch-transport (= 5.0.5)
    elasticsearch-api (5.0.5)
      multi_json
    elasticsearch-transport (5.0.5)
      faraday
      multi_json
    faraday (0.15.4)
      multipart-post (>= 1.2, < 3)
    ffi (1.11.1-java)
    filesize (0.2.0)
    fivemat (1.3.7)
    flores (0.0.7)
    fpm (1.3.3)
      arr-pm (~> 0.0.9)
      backports (>= 2.6.2)
      cabin (>= 0.6.0)
      childprocess
      clamp (~> 0.6)
      ffi
      json (>= 1.7.7)
    gem_publisher (1.5.0)
    gems (1.1.1)
      json
    hashdiff (1.0.0)
    i18n (1.6.0)
      concurrent-ruby (~> 1.0)
    insist (1.0.0)
    jrjackson (0.4.9-java)
    jruby-openssl (0.10.2-java)
    json (1.8.6-java)
    json-schema (2.8.1)
      addressable (>= 2.4)
    kramdown (1.14.0)
    logstash-devutils (1.3.6-java)
      fivemat
      gem_publisher
      insist (= 1.0.0)
      kramdown (= 1.14.0)
      logstash-core-plugin-api (>= 2.0, <= 2.99)
      minitar
      rake
      rspec (~> 3.0)
      rspec-wait
      stud (>= 0.0.20)
    logstash-output-elasticsearch (10.1.0-java)
      cabin (~> 0.6)
      logstash-core-plugin-api (>= 1.60, <= 2.99)
      manticore (>= 0.5.4, < 1.0.0)
      stud (~> 0.0, >= 0.0.17)
    manticore (0.6.4-java)
      openssl_pkcs8_pure
    method_source (0.9.2)
    minitar (0.9)
    multi_json (1.13.1)
    multipart-post (2.1.1)
    mustache (0.99.8)
    numerizer (0.1.1)
    octokit (4.14.0)
      sawyer (~> 0.8.0, >= 0.5.3)
    openssl_pkcs8_pure (0.0.0.2)
    paquet (0.2.1)
    pleaserun (0.0.30)
      cabin (> 0)
      clamp
      dotenv
      insist
      mustache (= 0.99.8)
      stud
    polyglot (0.3.5)
    pry (0.12.2-java)
      coderay (~> 1.1.0)
      method_source (~> 0.9.0)
      spoon (~> 0.0)
    public_suffix (4.0.1)
    puma (2.16.0-java)
    rack (1.6.11)
    rack-protection (1.5.5)
      rack
    rack-test (1.1.0)
      rack (>= 1.0, < 3)
    rake (12.3.3)
    rspec (3.8.0)
      rspec-core (~> 3.8.0)
      rspec-expectations (~> 3.8.0)
      rspec-mocks (~> 3.8.0)
    rspec-core (3.8.2)
      rspec-support (~> 3.8.0)
    rspec-expectations (3.8.4)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.8.0)
    rspec-mocks (3.8.1)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.8.0)
    rspec-support (3.8.2)
    rspec-wait (0.0.9)
      rspec (>= 3, < 4)
    ruby-progressbar (1.10.1)
    rubyzip (1.3.0)
    safe_yaml (1.0.5)
    sawyer (0.8.2)
      addressable (>= 2.3.5)
      faraday (> 0.8, < 2.0)
    sinatra (1.4.8)
      rack (~> 1.5)
      rack-protection (~> 1.4)
      tilt (>= 1.3, < 3)
    spoon (0.0.6)
      ffi
    stud (0.0.23)
    thread_safe (0.3.6-java)
    tilt (2.0.10)
    treetop (1.6.10)
      polyglot (~> 0.3)
    webmock (3.7.5)
      addressable (>= 2.3.6)
      crack (>= 0.3.2)
      hashdiff (>= 0.4.0, < 2.0.0)

PLATFORMS
  java

DEPENDENCIES
  atomic (~> 1)
  belzebuth
  benchmark-ips
  builder (~> 3)
  childprocess (~> 0.9)
  ci_reporter_rspec (~> 1)
  flores (~> 0.0.6)
  fpm (~> 1.3.3)
  gems (~> 1)
  json (~> 1.8.3)
  json-schema (~> 2)
  logstash-core!
  logstash-core-plugin-api!
  logstash-devutils (~> 1)
  logstash-output-elasticsearch
  octokit (~> 4)
  paquet (~> 0.2)
  pleaserun (~> 0.0.28)
  rack-test
  rake (~> 12)
  rspec (~> 3.5)
  ruby-progressbar (~> 1)
  rubyzip (~> 1)
  stud (~> 0.0.22)
  webmock (~> 3)

BUNDLED WITH
   1.17.3

To which Trivy outputs:

$ trivy --exit-code 1 --severity HIGH,CRITICAL --ignore-unfixed --clear-cache my-logstash:latest
2019-09-25T13:06:35.053-0700    INFO    Removing image caches...
2019-09-25T13:06:35.077-0700    INFO    Updating vulnerability database...
2019-09-25T13:07:28.155-0700    INFO    Detecting Ubuntu vulnerabilities...
2019-09-25T13:07:28.176-0700    INFO    Updating bundler Security DB...
2019-09-25T13:07:28.840-0700    INFO    Detecting bundler vulnerabilities...
2019-09-25T13:07:28.840-0700    INFO    Updating bundler Security DB...
2019-09-25T13:07:29.224-0700    INFO    Detecting bundler vulnerabilities...
2019-09-25T13:07:29.225-0700    INFO    Updating bundler Security DB...
2019-09-25T13:07:29.585-0700    INFO    Detecting bundler vulnerabilities...
2019-09-25T13:07:29.585-0700    INFO    Updating bundler Security DB...
2019-09-25T13:07:29.930-0700    INFO    Detecting bundler vulnerabilities...
2019-09-25T13:07:29.930-0700    INFO    Updating bundler Security DB...
2019-09-25T13:07:30.298-0700    INFO    Detecting bundler vulnerabilities...

logstash-7.3.2/vendor/bundle/jruby/2.5.0/gems/awesome_print-1.7.0/Gemfile.lock
==============================================================================
Total: 3 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 2, CRITICAL: 1)

+----------+------------------+----------+-------------------+---------------+--------------------------------+
| LIBRARY  | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |             TITLE              |
+----------+------------------+----------+-------------------+---------------+--------------------------------+
| nokogiri | CVE-2016-4658    | CRITICAL | 1.6.7.2           | >= 1.7.1      | libxml2: Use after free via    |
|          |                  |          |                   |               | namespace node in XPointer     |
|          |                  |          |                   |               | ranges                         |
+          +------------------+----------+                   +---------------+--------------------------------+
|          | CVE-2019-11068   | HIGH     |                   | >= 1.10.3     | libxslt: xsltCheckRead and     |
|          |                  |          |                   |               | xsltCheckWrite routines        |
|          |                  |          |                   |               | security bypass by crafted URL |
+          +------------------+          +                   +---------------+--------------------------------+
|          | CVE-2019-5477    |          |                   | >= 1.10.4     | Rexical Command Injection      |
|          |                  |          |                   |               | Vulnerability                  |
+----------+------------------+----------+-------------------+---------------+--------------------------------+

logstash-7.3.2/Gemfile.lock
===========================
Total: 6 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 5, CRITICAL: 1)

+----------+------------------+----------+-------------------+------------------------------+--------------------------------+
| LIBRARY  | VULNERABILITY ID | SEVERITY | INSTALLED VERSION |        FIXED VERSION         |             TITLE              |
+----------+------------------+----------+-------------------+------------------------------+--------------------------------+
| json     | CVE-2013-0269    | HIGH     | 1.8.6-java        | >= 1.7.7                     | rubygem-json: Denial of        |
|          |                  |          |                   |                              | Service and SQL Injection      |
+          +                  +          +                   +------------------------------+                                +
|          |                  |          |                   | ~> 1.5.5, ~> 1.6.8, >= 1.7.7 |                                |
|          |                  |          |                   |                              |                                |
+----------+------------------+----------+-------------------+------------------------------+--------------------------------+
| nokogiri | CVE-2016-4658    | CRITICAL | 1.10.4-java       | >= 1.7.1                     | libxml2: Use after free via    |
|          |                  |          |                   |                              | namespace node in XPointer     |
|          |                  |          |                   |                              | ranges                         |
+          +------------------+----------+                   +------------------------------+--------------------------------+
|          | CVE-2015-5312    | HIGH     |                   | >= 1.6.7.1                   | libxml2: CPU exhaustion when   |
|          |                  |          |                   |                              | processing specially crafted   |
|          |                  |          |                   |                              | XML input                      |
+          +------------------+          +                   +------------------------------+--------------------------------+
|          | CVE-2019-11068   |          |                   | >= 1.10.3                    | libxslt: xsltCheckRead and     |
|          |                  |          |                   |                              | xsltCheckWrite routines        |
|          |                  |          |                   |                              | security bypass by crafted URL |
+          +------------------+          +                   +------------------------------+--------------------------------+
|          | CVE-2019-5477    |          |                   | >= 1.10.4                    | Rexical Command Injection      |
|          |                  |          |                   |                              | Vulnerability                  |
+----------+------------------+----------+-------------------+------------------------------+--------------------------------+

logstash-7.3.2/vendor/bundle/jruby/2.5.0/gems/insist-1.0.0/Gemfile.lock
=======================================================================
Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)


speedtest-webspeed-logstash:latest (ubuntu 18.04)
=================================================
Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)


logstash-7.3.2/vendor/bundle/jruby/2.5.0/gems/http_parser.rb-0.6.0-java/Gemfile.lock
====================================================================================
Total: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 2, CRITICAL: 0)

+---------+------------------+----------+-------------------+------------------------------+--------------------------------+
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION |        FIXED VERSION         |             TITLE              |
+---------+------------------+----------+-------------------+------------------------------+--------------------------------+
| json    | CVE-2013-0269    | HIGH     | 1.8.0-java        | >= 1.7.7                     | rubygem-json: Denial of        |
|         |                  |          |                   |                              | Service and SQL Injection      |
+         +                  +          +                   +------------------------------+                                +
|         |                  |          |                   | ~> 1.5.5, ~> 1.6.8, >= 1.7.7 |                                |
|         |                  |          |                   |                              |                                |
+---------+------------------+----------+-------------------+------------------------------+--------------------------------+

logstash-7.3.2/vendor/bundle/jruby/2.5.0/gems/pleaserun-0.0.30/Gemfile.lock
===========================================================================
Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)

Seems like it's not specific to RubyGems.
I saw this when scanning kubernetes nginx ingress controller:

$ trivy --version
trivy version 0.1.6
$ trivy --severity HIGH,CRITICAL --ignore-unfixed quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.25.1
2019-09-26T16:10:07.139+0800    INFO    Updating vulnerability database...
2019-09-26T16:10:09.202+0800    INFO    Detecting Debian vulnerabilities...

quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.25.1 (debian 10.0)
===================================================================================
Total: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 2, CRITICAL: 0)

+---------------+------------------+----------+-------------------+------------------+--------------------------------+
|    LIBRARY    | VULNERABILITY ID | SEVERITY | INSTALLED VERSION |  FIXED VERSION   |             TITLE              |
+---------------+------------------+----------+-------------------+------------------+--------------------------------+
| libnghttp2-14 | CVE-2019-9511    | HIGH     | 1.36.0-2          | 1.36.0-2+deb10u1 | HTTP/2: large amount of data   |
|               |                  |          |                   |                  | requests leads to denial of    |
|               |                  |          |                   |                  | service                        |
+               +------------------+          +                   +                  +--------------------------------+
|               | CVE-2019-9513    |          |                   |                  | HTTP/2: flood using PRIORITY   |
|               |                  |          |                   |                  | frames resulting in excessive  |
|               |                  |          |                   |                  | resource consumption           |
+---------------+------------------+----------+-------------------+------------------+--------------------------------+

The 0.25.1 version is dedicated to fix these CVEs(https://github.com/kubernetes/ingress-nginx/releases/tag/nginx-0.25.1)

@gitlawr In your case, nginx is fixed, but libnghttp2-14 is detected.

root@d798feb11db8:/etc/nginx# apt-get changelog libnghttp2-14 2>&1 | grep -B2 -A4 CVE-2019-9511
nghttp2 (1.36.0-2+deb10u1) buster-security; urgency=high

  * Fix CVE-2019-9511 and CVE-2019-9513.

 -- Tomasz Buchert <[email protected]>  Fri, 23 Aug 2019 17:52:43 +0200

nghttp2 (1.36.0-2) unstable; urgency=medium

This seems true.

@knqyf263 Thanks for the explanation.

trivy fluent/fluentd:latest currently reproduces this with:
json | CVE-2013-0269 | HIGH | 1.8.0-java | ~> 1.5.5, ~> 1.6.8, >= 1.7.7 | rubygem-json

Tested using latest version of Trivy (0.4.2).

I can confirm this issue still exists as well:

./Gemfile.lock
====================================================
Total: 5 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 4, CRITICAL: 1)

+----------+------------------+----------+-------------------+------------------------------+--------------------------------+
| LIBRARY  | VULNERABILITY ID | SEVERITY | INSTALLED VERSION |        FIXED VERSION         |             TITLE              |
+----------+------------------+----------+-------------------+------------------------------+--------------------------------+
| json     | CVE-2013-0269    | HIGH     | 2.3.0-java        | ~> 1.5.5, ~> 1.6.8, >= 1.7.7 | rubygem-json: Denial of        |
|          |                  |          |                   |                              | Service and SQL Injection      |
+----------+------------------+----------+-------------------+------------------------------+--------------------------------+
| nokogiri | CVE-2016-4658    | CRITICAL | 1.10.9-java       | >= 1.7.1                     | libxml2: Use after free via    |
|          |                  |          |                   |                              | namespace node in XPointer     |
|          |                  |          |                   |                              | ranges                         |
+          +------------------+----------+                   +------------------------------+--------------------------------+
|          | CVE-2015-5312    | HIGH     |                   | >= 1.6.7.1                   | libxml2: CPU exhaustion when   |
|          |                  |          |                   |                              | processing specially crafted   |
|          |                  |          |                   |                              | XML input                      |
+          +------------------+          +                   +------------------------------+--------------------------------+
|          | CVE-2019-11068   |          |                   | >= 1.10.3                    | libxslt: xsltCheckRead and     |
|          |                  |          |                   |                              | xsltCheckWrite routines        |
|          |                  |          |                   |                              | security bypass by crafted URL |
+          +------------------+          +                   +------------------------------+--------------------------------+
|          | CVE-2019-5477    |          |                   | >= 1.10.4                    | Rexical Command Injection      |
|          |                  |          |                   |                              | Vulnerability                  |
+----------+------------------+----------+-------------------+------------------------------+--------------------------------+

Those installed gem versions shouldn't trip Trivy up.

$ trivy --version

Version: 0.6.0
Vulnerability DB:
  Type: Light
  Version: 1
  UpdatedAt: 2020-04-23 12:07:58.740214484 +0000 UTC
  NextUpdate: 2020-04-24 00:07:58.740214184 +0000 UTC

Hi @rahul2393, could you look into it? Trivy compares the version here.
https://github.com/aquasecurity/trivy/blob/master/pkg/detector/library/bundler/advisory.go#L55-L60

It calls MatchVersions using go-version.
https://github.com/aquasecurity/trivy/blob/master/pkg/scanner/utils/utils.go#L16-L28

go-version is based on semantic versioning, but some gem libraries look like adopting different versioning.
https://semver.org/

If Gem has different versioning, we probably need to implement the library for Gem versioning. At first, it would be great if you investigate it. After that, let's discuss we need to implement the library. Ruby has the Version class and we might need to re-write it in Golang.
https://ruby-doc.org/stdlib-2.5.0/libdoc/rubygems/rdoc/Gem/Version.html

Ok Ack, will create PR

@rahul2393 We might be able to use this library. It is Go library for PHP version comparison, but it seems to work with Ruby versioning as well. At first, we should look into the specification of Ruby/Gem versioning, and then let's try this library.
https://github.com/mcuadros/go-version

@knqyf263 Please review this added some tests here

Hi all, I developed go-gem-version finally. I believe #740 addressed this issue and it will be delivered at v0.13.0.

I'm not sure if this work around will suffice for others but we were having the same issue on our instance and moving the Dockerfile from .docker/Dockerfile to .docker/app/Dockerfile and updating the build command with --file .docker/app/Dockerfile fixes the issue for. Not sure why.

Cancel that; it stopped working the second time around 馃し

Was this page helpful?
0 / 5 - 0 ratings

Related issues

patrickbaber picture patrickbaber  路  3Comments

ahmddp picture ahmddp  路  4Comments

itamarst picture itamarst  路  3Comments

dendi picture dendi  路  3Comments

abedra picture abedra  路  4Comments