Use Python in Docker, not in your OS

Protect your system from malware and ransomware

Miguel A. Calles · Serverless CISO
Geek Culture
Published in
6 min readJul 25, 2022

--

We can keep our computers isolated from malicious Python packages and vulnerabilities by using Docker containers. It’s like protecting ourselves from a vicious snake bite.

Photo by Nick Rickert on Unsplash

What are Docker containers and why should we use them?

Docker is a software technology that creates a container that runs on our computer. A container is like running a mini-computer within ours and restricts access to our files.

The problem with running Python on our computer is the growth of malicious Python packages. Some malicious actors purposely put malware in packages. They create packages with similar names (called typosquatting) hoping we will install the incorrect version so they can deliver the malware.

These types of attacks have been growing significantly and will continue to be an issue in 2022 and future years.

What if we installed a malicious package and we can limit the extent of the damage. That is where containers can help.

Suppose we installed a package that deployed ransomware. All our files would become a victim of the ransomware attack if we were running Python on our computer.

Suppose we installed it inside a container. A properly configured container will limit access to the files added to the container. In theory, only those specific files will be compromised and our files should be protected. We can stop the container, delete the container image, purge all files associated with the container, and run an antivirus scan just to be safe. Given we committed our code to a software repository, we probably only lost a little bit of our code.

Using a Docker container to run Python is like putting our code in quarantine so that an infection does not put a strain on the whole computer.

How do I set up a container that runs Python on my machine?

Start by installing Docker Desktop on our development machine. We will want to create a Docker account also to take advantage Docker scan feature that we will discuss later.

After we install it, go to the settings.

Enable “Docker Compose V2” in the “General” section.

General settings.

Set the desired resource load in the “Resources Advanced” section.

Advanced Resources settings.

Ensure software updates are enabled.

Software Updates settings.

Go to our code folder. Create a file called “docker-compose.yml” in the top-level directory (or in every folder where we want a customized container).

version: "3"
services:
dev:
image: "circleci/python"
working_dir: /home/circleci
volumes:
- ./:/home/circleci

The Docker Compose file creates and runs a Docker container.

The dev: property defines a Docker Compose container named dev.

The image: property defines the container. The example uses an official CircleCI container image.

The working_dir: property defines the home directory as /home/circle. When we start the container it will show ~ as the current folder, which is a Linux shorthand for the circleci user’s home directory.

The volumes: property allows running Docker within the container, puts all the files where the docker-compose.yml file exists, and mounts them to the /home/circleci directory within the container. (We can delete the first line if we do not need Docker running within the container.)

A benefit of using a CircleCI image is that it includes tools typically available in a Continuous Integration (CI) environment, e.g., git.

In our computer’s terminal, run the following command to start the container.

docker compose run --rm dev bash
# Or the following if Docker Compose v2 was not checked above
docker-compose run --rm dev bash

We will now see a prompt like circleci@502104098e72:~$ in the terminal. This means our terminal is now inside the Docker container running Python.

Bonus: Customize the command prompt to make it more meaningful to you with the PS1 Linux variable.

circleci@502104098e72:~$ PS1="MyProject:\w$ "
MyProject:~$

Type the ls command to see our files. We should see the files within the directory.

Open Docker Desktop and we will see our container running.

A container is running

We can now run an install command within the container, such as, pip install requests or pip3 install requests. Note: pip may not be installed in our container depending on which one we use. To install pip, do the following.

# install pip when not already installed
wget https://bootstrap.pypa.io/get-pip.py
python3 get-pip.py

(If Python is installed on our machine, we can try installing a different global package in our container. We open a new terminal window, try running the global package and we should get an error because it is only installed in our container.)

In the container’s terminal, type the exit command. Go to Docker Desktop and we should no longer see the container.

No container is running.

The --rm flag in the command docker compose run tells Docker to delete the container after it terminates. This way we can keep our machine cleaner.

Keeping Docker up to date and clean

We should apply the Docker software updates when they become available.

After we apply the updates, we should scan our container for vulnerabilities with a Docker scan.

We need to accept the license to get started with the Docker scan.

docker scan --accept-license --version

We can scan our container with the following command.

docker scan circleci/python

The scan output will recommend which container image to use. We will update the image: property within the docker-compose.yml file to have the recommended image.

Every so often we should clean up the images by going to the “Images” tab in Docker Desktop and deleting them.

Cleaning up images.

And remove old volumes by going to the “Volumes” tab and deleting them.

Removing volumes.

Conclusion

Using Docker containers is one way to protect our computers from malicious Python packages and vulnerabilities because code execution and runtimes are isolated to the container.

Before you go

There are other articles you might enjoy.

--

--

Miguel A. Calles · Serverless CISO
Geek Culture

Author of "Serverless Security" · Specializing in CMMC, SOC 2, serverless & engineering.