nvd-clojure

repository·main·Indexed 43 days ago

https://github.com/rm-hull/nvd-clojure

A dependency checker tool for Clojure projects that identifies known security vulnerabilities in a project's classpath using the National Vulnerability Database (NVD) and the OWASP DependencyCheck library. It supports integration with Leiningen, Clojure CLI, and Clojure CLI Tools, utilizing .edn configuration files to manage API keys, CVSS fail thresholds, and CVE suppressions.

Tokens
2K
Snippets
7
Records
10
Agent score
5%

What's inside nvd-clojure

  1. Avoid classpath interference

    main

    To ensure nvd-clojure functions correctly and to avoid security issues where a project's dependencies overlap with nvd-clojure's dependencies, you must decouple the nvd-clojure classpath from the classpath being analyzed.

    Follow the provided installation/usage instructions carefully. For non-Clojure Tools environments (like Leiningen or Clojure CLI), it is recommended to install nvd-clojure by creating a dedicated project directory (containing a project.clj or deps.edn) that acts as a 'subproject' within your main project. This directory should be treated similarly to a .github or .circleci directory.

  2. Migrate from .json to .edn configuration format

    main

    The .json configuration format is legacy. To migrate to the modern .edn format, extract the map associated with the "nvd" key from your JSON file, convert string keys to keywords, and save it as nvd-clojure.edn.

    If you name the file nvd-clojure.edn (the default), you can use an empty string "" in your CLI/CI invocations to specify the filename. Using this shorthand allows the command to automatically create the .edn file with useful defaults if it is missing in a new project.

    Migration Example:

    From (Legacy JSON):

    {
     "delete-config?": false,
     "nvd": {"suppression-file": "nvd_suppressions.xml"}
    }

    To (Modern EDN):

    {:suppression-file "nvd_suppressions.xml"}
    -{"delete-config?": false,
    - "nvd": {"suppression-file": "nvd_suppressions.xml"}}
    +{:suppression-file "nvd_suppressions.xml"}
  3. Install and use nvd-clojure with Leiningen

    main

    To use nvd-clojure with Leiningen, do not add it as a dependency or plugin to the project you want to analyze. Instead, create a separate 'helper' project in the same repository.

    1. Create a new project with a project.clj containing nvd-clojure and clojure as dependencies:
    (defproject nvd-helper "local"
      :description "nvd-clojure helper project"
      :dependencies [[nvd-clojure "5.3.0"]
                     [org.clojure/clojure "1.12.3"]]
      :jvm-opts ["-Dclojure.main.report=stderr"])
    1. Run the check from within this helper project, passing the classpath of your target project as an argument:
    lein with-profile -user run -m nvd.task.check "nvd-clojure.edn" "$(cd <YOUR_PROJECT>; lein with-profile -user,-dev classpath)"

    *Note: The first argument is your configuration file. Use "" to use the default nvd-clojure.edn.

  4. Remediate CVEs found by nvd-clojure

    main

    When nvd-clojure reports a CVE, you can remediate it using several strategies depending on your project needs:

    • Dependency Management:
      • Upgrade a direct dependency.
      • Replace a dependency with an alternative (e.g., a different JSON parser).
      • Upgrade a managed dependency.
      • Declare a transitive dependency at a newer version.
      • Upgrade a transitive dependency.
      • Remove a direct dependency.
      • Add :exclusions to remove a specific transitive dependency.
    • Suppression:
      • Add an entry to nvd-suppressions.xml. Suppressions can be:
        • Fine-grained (exact match).
        • Coarse-grained (wildcard match).
        • Temporary (includes an expiration date).

    Note: Automated remediation is not recommended as it cannot assess the safest or best choice for your specific application code. Manual, thoughtful remediation is preferred.

  5. Configure logging for nvd-clojure

    main

    You can override default logging in two ways:

    1. Classpath Resource: Provide a simplelogger.properties file on the nvd-clojure classpath (not your project's classpath).

    2. Java System Properties: Use -D flags when invoking the Clojure command.

    Example using system properties to set a specific logger to error level:

    clojure -J-Dclojure.main.report=stderr -J-Dorg.slf4j.simpleLogger.log.org.apache.commons=error -Tnvd nvd.task/check
    clojure -J-Dclojure.main.report=stderr -J-Dorg.slf4j.simpleLogger.log.org.apache.commons=error -Tnvd nvd.task/check # ...
  6. Install and use nvd-clojure with Clojure CLI

    main

    To use nvd-clojure with the Clojure CLI, create a separate project containing only nvd-clojure. Do not add it to the deps.edn of the project being analyzed.

    1. Create a helper project with nvd-clojure in its deps.edn.

    2. Run the check by passing the target project's classpath using -Spath:

    clojure -J-Dclojure.main.report=stderr -M -m nvd.task.check "nvd-clojure.edn" "$(cd <YOUR_PROJECT>; clojure -Spath -A:any:aliases)"

    *Note: The -Spath command should reflect a production-like classpath (excluding dev/test tools).

  7. Install and use nvd-clojure as a Clojure CLI Tool

    main

    If you have Clojure CLI version 1.10.3.933 or later, you can install nvd-clojure as a tool.

    1. Install the tool:
    clojure -Ttools install nvd-clojure/nvd-clojure '{:mvn/version "RELEASE"}' :as nvd
    1. Run the check:
    clojure -J-Dclojure.main.report=stderr -Tnvd nvd.task/check :classpath """$(clojure -Spath -A:any:aliases)""" :config-filename """nvd-config.edn"""

    *Note: Use escaped double quotes around the arguments to ensure Clojure reads them as strings. The :config-filename denotes the .edn file with extra options.

  8. Handle OSS Index HTTP errors and flakiness

    main

    If you encounter HTTP errors from OSS Index during a run, you can prevent these errors from failing your build by setting the following configuration key to true:

    :ossindex-warn-only-on-remote-errors true

    Warning: Enabling this setting can cause false negatives (missing actual vulnerabilities). It is recommended to use this setting only temporarily and monitor public issue reports to see if the flakiness has been resolved.

    :ossindex-warn-only-on-remote-errors true
  9. Configure nvd-clojure via .edn file

    main

    Customization is handled via an .edn configuration file.

    • When running via lein -m, the filename is the first command-line argument.
    • When running via Clojure Tools (-Tnvd), use the :config-filename option.

    Example invocation with a custom config:

    clojure -Tnvd nvd.task/check :classpath """$(clojure -Spath)""" :config-filename """nvd-config.edn"""

    If the specified file does not exist, nvd-clojure will automatically create it with default contents and comments.

  10. Reference: nvd-clojure configuration options

    main

    The following keys can be used in your .edn configuration file to customize the vulnerability check behavior:

    KeyDescription
    :nvd-apiA map containing :key (MANDATORY unless NVD_API_TOKEN env var is set). Also supports :endpoint, :delay, :max-retry-count, :valid-for-hours, and :datafeed.
    :fail-thresholdThe highest CVSS score allowed before the process exits with an error. Default is 0 (fails if any vulnerability > 0 is found). Set to 11 to never fail, or -1 to fail on score 0 vulnerabilities.
    :data-directoryDirectory for DependencyCheck data. Default is the DependencyCheck data dir.
    :suppression-filePath to an XML file for permanently/temporarily suppressing CVEs.
    :verbose-summaryBoolean. If true, the summary table includes severity for all dependencies. If false, only low/high severity packages are shown.
    :output-dirDirectory where reports are saved. Default is target/nvd/.
    :throw-if-check-unsuccessfulIf true, the program exits by throwing an exception instead of calling System/exit.
    :ossindex-user / :ossindex-passwordMANDATORY within the :analyzer map if using the OSS Index analyzer. Alternatively, use ANALYZER_OSSINDEX_USER and ANALYZER_OSSINDEX_PASSWORD env vars.