Scanning your Conda environment for security vulnerabilities

You don’t want to deploy an application that has security vulnerabilities. That means your own code, but also third-party dependencies: it doesn’t matter how secure your code is if it’s exposing a TLS socket with a version of OpenSSL that has a remote code execution vulnerability.

For pip-based Python applications, you’d usually run vulnerability scanners on Python dependencies like Django, and on system packages like OpenSSL. With Conda, however, the situation is a little different: Conda combines both types of packages into one place. In addition, most vulnerability scanners don’t support Conda.

Let’s see what makes Conda different, and how you can scan packages for known vulnerabilities.

The Conda difference

Typically for a Python application, C libraries like OpenSSL and applications like Nginx would come from a Linux distribution like Ubuntu, and Python dependencies would be installed from PyPI using pip (or poetry or pipenv). Additionally, Python binary packages (“wheels”) can include shared C libraries they depend on.

Conda uses a different model: the Conda package repositories have packages for C libraries, C applications, Python libraries, and so on, all in one place. Instead of some packages coming from the Linux distribution, and some from the Python package repository, everything gets installed from the same place.

In practice, Conda relies on the system C library, so you still want to run a security vulnerability on the underlying Linux distribution’s system package. But the bulk of security vulnerabilities, whether it’s OpenSSL, Nginx, or a Python package, will come from Conda packages.

Standard tools

Security vulnerability scanners that are built for checking Python dependencies are not sufficient for Conda because they only understand Python packages.

For example, let’s say I have a Conda environment with some security vulnerabilities. I can use the safety tool to find security vulnerabilities in Python packages:

$ conda activate example
(example) $ pip install safety
(example) $ safety check
| package          | installed | affected    | ID       |
| pip              | 20.2.4    | <21.1       | 40291    |
| cryptography     | 3.2.1     | <3.3        | 39252    |
| cryptography     | 3.2.1     | <3.3.2      | 39606    |

And that works… but it won’t catch problems in the Conda packages that aren’t Python packages.

Jake: a vulnerability scanner for Conda

In order to scan for all security vulnerabilities, we need a tool that knows about all the different types of software that end up in the Conda package repositories, beyond just Python libraries. The only tool I know of that does is Jake, which relies on the Sonatype OSS Index of security vulnerabilities.

To begin with, Jake also supports pip:

(example) $ pip install jake
(example) $ pip list | jake ddt | grep VULNERABLE
[38/39] - pkg:pypi/cryptography@3.2.1 [VULNERABLE]
[39/39] - pkg:pypi/jinja2@2.11.2 [VULNERABLE]

There’s a lot more details in the output if you omit the grep.

One thing to notice is that safety doesn’t know about the Jinja vulnerability, for some reason, and Jake in turn missed the pip vulnerability that safety knew about. None of the tools or underlying databases will catch everything.

Beyond pip packages, Jake also supports Conda packages, and this is where it goes far beyond what Python-specific tools can do.

We need to use conda list and the -c option, and it’s very important not to omit the latter, otherwise it will just give you Python vulnerabilities. With those options, you can find security vulnerabilities in all the Conda packages:

(example) $ conda list --json | jake ddt --type=CONDA_JSON | grep VULNERABLE
[59/63] - pkg:conda/cryptography@3.2.1 [VULNERABLE]
[60/63] - pkg:conda/jinja2@2.11.2 [VULNERABLE]
[61/63] - pkg:conda/openssl@1.1.1h [VULNERABLE]
[62/63] - pkg:conda/python@3.8.6 [VULNERABLE]
[63/63] - pkg:conda/sqlite@3.33.0 [VULNERABLE]

Security vulnerabilities tools that scan only Python packages would never find a vulnerability in OpenSSL.

That being said: Jake doesn’t yet support Conda-Forge packages very well, mostly it focuses on the default Anaconda package channel.

Scan your dependencies!

Scanning dependencies for vulnerabilities is an important part of keeping your application secure. If you’re not already doing it, now’s a good time to take 20 minutes and add Jake to your CI pipeline.