Vulnerability (CVE) scanner for Nix/NixOS [maintainer=@henrirosten]
Find a file
Henri Rosten 469a5d1d3d Prepare release 1.12.2
Signed-off-by: Henri Rosten <henri.rosten@unikie.com>
2025-10-13 09:40:04 +03:00
.github Bump cachix/install-nix-action from 31.6.0 to 31.6.1 2025-09-09 11:01:36 +03:00
doc Add --profile option to scan user environments (#72) 2021-06-03 21:17:46 +02:00
nix Fix devshell 2025-09-09 09:54:05 +03:00
src/vulnix Back to using NIST for NVD data 2025-10-10 13:41:47 +03:00
.editorconfig README.rst: Add syntax highlighting to code blocks (#86) 2022-10-13 14:38:18 +02:00
.gitignore Initial man pages 2018-04-19 17:39:29 +02:00
CHANGES.rst Prepare release 1.12.2 2025-10-13 09:40:04 +03:00
default.nix Apply initial treefmt formatters 2024-12-20 07:24:32 +02:00
flake.lock Flake update 2025-09-09 09:54:05 +03:00
flake.nix Apply initial treefmt formatters 2024-12-20 07:24:32 +02:00
HACKING.rst Fix incorrect processing of the 'until' field 2019-03-09 09:23:18 +01:00
LICENSE remote (outdated) year from license 2019-10-24 11:09:32 +02:00
MANIFEST.in Fix packaging bug 2019-11-14 13:28:11 +01:00
README.rst Remove new maintainer needed announcement 2024-11-28 07:55:41 +02:00
setup.cfg Remove pytest-flake8 check 2024-12-20 07:24:32 +02:00
setup.py Apply ruff formatter changes 2024-12-22 09:00:52 +02:00
shell.nix Apply initial treefmt formatters 2024-12-20 07:24:32 +02:00
VERSION Prepare release 1.12.2 2025-10-13 09:40:04 +03:00

Nix(OS) vulnerability scanner
=============================

This is a utility that validates a Nix store for any packages that are
reachable from live paths and likely to be affected by vulnerabilities
listed in the NVD.

It implements a CLI utility to inspect the current status and a
monitoring integration for Sensu.

Example output

.. code:: text

  2 derivations with active advisories

  ------------------------------------------------------------------------
  binutils-2.31.1

  /nix/store/zc1lbkaf9l9hlsp1jdiq3si56nsglymh-binutils-2.31.1.drv
  CVE                                                CVSSv3
  https://nvd.nist.gov/vuln/detail/CVE-2018-1000876  7.8
  https://nvd.nist.gov/vuln/detail/CVE-2018-20657    7.5
  https://nvd.nist.gov/vuln/detail/CVE-2018-20712    6.5

  ------------------------------------------------------------------------
  libssh2-1.9.0

  /nix/store/mfpfclry68r4sv4mcc9hb88z0lb9jk1c-libssh2-1.9.0.drv
  CVE                                                CVSSv3
  https://nvd.nist.gov/vuln/detail/CVE-2019-17498    8.1


Theory of operation
-------------------

``vulnix`` pulls all published CVEs from NIST_ and caches them locally. It
matches name and version of all derivations referenced from the command line
against known CVE entries. A *whitelist* is used to filter out unwanted results.

Matching Nix package names to NVD products is currently done via a coarse
heuristic. First, a direct match is tried. If no product can be found,
variations with lower case and underscore instead of hyphen are tried. It is
clear that this mapping is too simplistic and needs to be improved in future
versions.


System requirements
-------------------

- Depends on common Nix tools like ``nix-store``. These are expected to be in
  $PATH.
- Depends on being able to interact with the Nix store database
  (/nix/var/nix/db). This means that it must either run as the same user that
  owns the Nix store database or ``nix-daemon`` must be active.
- Parses ``*.drv`` files directly. Tested with Nix >=1.10 and 2.x.
- It refuses to work without some locale environment settings. Try ``export
  LANG=C.UTF-8`` if you see encoding errors.


Usage Example
=============

- What vulnerabilities are listed for my current system

.. code:: shell

  vulnix --system

- Check ``nix-build`` output together with its transitive closure

.. code:: shell

  vulnix result/

- Check all passed derivations, but don't determine requisites

.. code:: shell

  vulnix -R /nix/store/*.drv

- JSON output for machine post-processing

.. code:: shell

  vulnix --json /nix/store/my-derivation.drv

See ``vulnix --help`` for a list of all options.


Whitelisting
============

``vulnix`` output may contain false positives, unfixable packages or stuff which
is known to be addressed. The *whitelist* feature allows to exclude packages
matching certain criteria.

Usage
-----

Load whitelists from either local files or HTTP servers

.. code:: shell

  vulnix -w /path/to/whitelist.toml \
         -w https://example.org/published-whitelist.toml

Syntax
------

Whitelists are TOML_ files which contain the package to be filtered as section
headers, followed by further per-package options.

Section headings - package selection
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Exclude a package at a specific version

.. code:: toml

  ["openjpeg-2.3.0"]

Exclude a package regardless of version (additional CVE filters may apply, see
below)

.. code:: toml

  ["openjpeg"]

Exclude all packages (see below for CVE filters, again)

.. code:: toml

  ["*"]

Options
^^^^^^^

cve
  List of CVE identifiers to match. The whitelist rule is valid as long as the
  detected CVEs are a subset of the CVEs listed here. If additional CVEs are
  detected, this whitelist rule is not effective anymore.

until
  Date in the form "YYYY-MM-DD" which confines this rule's lifetime. On the
  specified date and later, this whitelist rule is not effective anymore.

issue_url
  URL or list of URLs that point to any issue tracker. Informational only.

comment
  String or list of strings containing free text. Informational only.


Examples
--------

Create a ticket on your favourite issue tracker. Estimate the time to get the
vulnerable package fixed. Create whitelist entry:

.. code:: toml

  ["ffmpeg-3.4.2"]
  cve = ["CVE-2018-6912", "CVE-2018-7557"]
  until = "2018-05-01"
  issue_url = "https://issues.example.com/29952"
  comment = "need to backport patch"

This particular version of ffmpeg will be left out from reports until either
another CVE gets published or the specified date is reached.


CVE patch auto-detection
========================

``vulnix`` will inspect derivations for patches which supposedly fix specific
CVEs. When a patch filename contains one or more CVE identifiers, these will not
reported anymore. Example Nix code:

.. code:: nix

  {
    patches = [ ./CVE-2018-6951.patch ];
  }

Patches which fix multiple CVEs should name them all with a non-numeric
separator, e.g. ``CVE-2017-14159+CVE-2017-17740.patch``.

Auto-detection even works when patches are pulled via ``fetchpatch`` and friends
as long as there is a CVE identifier in the name. Example:

.. code:: nix

  {
    patches = [
      (fetchpatch {
        name = "CVE-2018-9055.patch";
        url = http://paste.opensuse.org/view/raw/330751ce;
        sha256 = "0m798m6c4v9yyhql7x684j5kppcm6884n1rrb9ljz8p9aqq2jqnm";
      })
    ];
  }


.. _NIST: https://nvd.nist.gov/vuln/
.. _TOML: https://github.com/toml-lang/toml/