Introducing vulnix - a vulnerability scanner for NixOS
As we are in the preliminary phase of releasing our new NixOS based platform as a stable, security related topics gain further momentum. The question of how and when a system is affected by a security flaw is certainly not only related to our use-case, we suspect this to be of importance for some.
Just a glance over the nixpkgs-issue tracker and the mailinglist shows:
- #13515 (nixpkgs issue)
- 1.severity: security (nixpkgs issue label)
- nix-audit [1] [2] (nix-dev mailinglist)
This is where vulnix comes into play. It reverses the nixpkgs-monitor approach answering the question, which of my current active garbage collecting roots is affected by a known CVE. Indiviually(!) for every running system.
At first we ask the nix-store to show us the derivations of the live gc-roots, we then take these derivation files (*.drv) and mock them with Derive Class as they happen to fit the Python syntax ;-). As a result we get an object, carrying the derivations properties like name, builder etc and a set of methods to check them against (potential) vulnerabilities. This is what the store.update() method is for.
store = Store () store.update()Then we collect the vulnerabilities in two steps. nvd.update() downloads the gzip'ed nvdcve-files from NIST. In nvd.parse() we translate the XML document to the Common Platform Enumeration (cpe) format, a naming scheme used by NIST to structure affected software products in categories like vendor, version and the likes. This helps to match derivations and vulnerabilities.
nvd = NVD () nvd.update () nvd.parse ()As the naming scheme in the CVEs does not necessarily needs to fit the bill of NixOS derivations, and the match atm is solely decided by name and optionally version we had the need to exclude some issues manually. Providing a yaml file (whitelist.yaml). As an example we encountered the access derivation in Nix which lead to a match with Microft Access related entries.
whitelist = WhiteList() whitelist.parse()
whitelist.yaml
This is taken from our unit test. The options will be extended in the process ( we are experimenting with state flags, to produce more subtle check informations). All the properties work as filter and will be linked together, you may exclude a whole CVE id or specify a certain package in a specific version, where the issues is known to you or whatever good reason you come up with. We found it came in handy to either match properties of the derivation (name, version) or the CVE related ones (vendor, product).$ cat src/vulnix/tests/whitelist.yaml
- cve: CVE-2015-2503 comment: microsoft access, accidentally matching the 'access' derivation https://plan.flyingcircus.io/issues/18544 - name: libxslt - cve: CVE-2015-7696 name: unzip - derivation: libxslt version: '2.0' - vendor: microsoft product: access
Hands-On
Installation
$ hg clone https://bitbucket.org/flyingcircus/vulnix $ cd ./vulnix $ ./bootstrap.sh
Usage
Disclaimer: As of today we still tweak the heuristics and the output format and thus haven't done too much for the commandline invocation.$ bin/vulnix
Result
This is a pick running on my Mac, where we get the package which is (might be) affected (top left), then the matching and the referring derivation. It's actually quite self explanatory. We intend to use this format for the verbose output field of our sensu infrastructure.=========================================================== expat-2.1.0 /nix/store/bb83049z7mqdq5w629lnaflryspshrlw-expat-2.1.0.drv Referenced by: /nix/store/y495f58sw9i6912bvnlhckgl9y89kfkh-cmake-3.4.3.drv Used by: /Users/plumps/d/personal/pkgs/libspotify/result /Nix/var/nix/profiles/default-10-link /Nix/var/nix/profiles/default-11-link /Nix/var/nix/profiles/default-12-link /Nix/var/nix/profiles/default-13-link /Nix/var/nix/profiles/default-14-link /Nix/var/nix/profiles/default-15-link /Nix/var/nix/profiles/default-16-link /Nix/var/nix/profiles/default-17-link /Nix/var/nix/profiles/default-5-link /Nix/var/nix/profiles/default-6-link /Nix/var/nix/profiles/default-7-link /Nix/var/nix/profiles/default-8-link /Nix/var/nix/profiles/default-9-link CVEs: https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-1283 ===========================================================

Get in touch
Call us or send us an email.
Contact
mail: mail@flyingcircus.io
fon: +49 345 219 401 0
fax: +49 345 219 401 28
Address
Flying Circus Internet Operations GmbH
Leipziger Str. 70/71
06108 Halle (Saale)
GERMANY
Commercial register
AG Stendal as HRB 21169
VAT ID: DE297423633
Managing Directors:
Christian Theune, Christian Zagrodnick