rm-hull / nvd-clojure

National Vulnerability Database dependency checker for Clojure projects
MIT License
278 stars 36 forks source link

The classpath for Leiningen and Clojure CLI is worked out differently #64

Closed dotemacs closed 3 years ago

dotemacs commented 3 years ago

tl;dr: the results of vulnerability checking of a repo via Leiningen and Clojure CLI differ, this is due to the way the classpath is created by those tools. I think that I have a solution. Read on for details.

See the output of the run on a sample repo (https://github.com/dotemacs/pdfboxing):

[alex@~/dev/clojure/repos/pdfboxing]$ lein nvd check
Picked up JAVA_TOOL_OPTIONS: -Djava.awt.headless=true
Checking dependencies for pdfboxing 0.1.15.1-SNAPSHOT ...
  using nvd-clojure:  and dependency-check: 5.3.2

0 vulnerabilities detected. Severity: NONE
Detailed reports saved in: /Users/alex/dev/clojure/repos/pdfboxing/target/nvd

   *** THIS REPORT IS WITHOUT WARRANTY ***

[alex@~/dev/clojure/repos/pdfboxing]$ clj -M:nvd
Picked up JAVA_TOOL_OPTIONS: -Djava.awt.headless=true
Picked up JAVA_TOOL_OPTIONS: -Djava.awt.headless=true
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Checking dependencies for unknown  ...
  using nvd-clojure:  and dependency-check: 5.3.2
00:00  INFO: Vulnerability found: jquery below 3.5.0
00:00  INFO: Vulnerability found: jquery below 3.5.0
+------------------------------------------------------+--------------------------------+
| dependency                                           | status                         |
+------------------------------------------------------+--------------------------------+
| dependency-check-core-5.3.2.jar: jquery-3.4.1.min.js | CVE-2020-11022, CVE-2020-11023 |
| failureaccess-1.0.1.jar                              | CVE-2020-8908                  |
| guava-28.2-jre.jar                                   | CVE-2020-8908                  |
| httpclient-4.5.3.jar                                 | CVE-2020-13956                 |
+------------------------------------------------------+--------------------------------+

5 vulnerabilities detected. Severity: MEDIUM
Detailed reports saved in: /Users/alex/dev/clojure/repos/pdfboxing/target/nvd

   *** THIS REPORT IS WITHOUT WARRANTY ***

[alex@~/dev/clojure/repos/pdfboxing]$

I've added lein-nvd as a plugin in my $HOME/.lein/profiles.clj, whereas my deps.edn is:

{:description "Clojure PDF manipulation library & wrapper for PDFBox"
 :url "https://github.com/dotemacs/pdfboxing"
 :paths ["src"]
 :deps {org.clojure/clojure {:mvn/version "1.10.1"}
        org.apache.pdfbox/pdfbox {:mvn/version "2.0.21"}}
 :license {:name "BSD"
           :url "http://www.opensource.org/licenses/bsd-license"}
 :aliases {:test {:extra-paths ["test"]}
           :runner {:extra-deps {com.cognitect/test-runner
                                 {:git/url "https://github.com/cognitect-labs/test-runner"
                                  :sha "76568540e7f40268ad2b646110f237a60295fa3c"}}
                    :main-opts ["-m" "cognitect.test-runner" "-d" "test"]}
           :nvd {:extra-deps {lein-nvd/lein-nvd {:mvn/version "1.4.1"
                                                 :exclusions [org.slf4j/slf4j-simple]}}
                 :main-opts ["-m" "nvd.task.check"]}}}

The issue here is that when I ran clj -M:nvd it obviously picked up the classpath from that alias, but by doing that, it included the libraries needed by nvd.task.check/-main to run.

My thinking is that the way to work out the classpath for a project/library is not to use the classpath it is running from, when using Clojure CLI, but to read deps.edn, in particular the values under :deps key, and construct a classpath from that. See this example for details: https://github.com/clojure/tools.deps.alpha/blob/master/API.md#example-usage

Putting this here in case somebody else stumbles upon it. I plan on tackling this soon, but sharing the notes just in case I don't get to it.

rm-hull commented 3 years ago

Also, minor points (probably unrelated to this issue):

dotemacs commented 3 years ago

Also, minor points (probably unrelated to this issue):

  • it should be showing the nvd version number here using nvd-clojure: and dependency-check: 5.3.2
  • for deps.edn, can we show the project name instead of unknown here Checking dependencies for unknown ...

Good points, I'll try to tackle them in the next PR, specifically targeting those points.

While we're talking about them, getting the version number for nvd-clojure can be derived from project.clj. But for some other project, using Clojure CLI, you can't get the name from deps.edn, because the name is not specified like it would be in project.clj. So I'd have to think that one through...