Skip to main content

Using UBI images to minimize container vulnerabilities

Artikel von
Headshot of Rags Srinivas

Rags Srinivas

27. März 2020

0 Min. Lesezeit

At Snyk, we work hard to continue improving container and cloud-native security solutions. As part of this effort, Snyk Container empowers developers to fully own the security of their container images.

One common source of vulnerabilities in containers is the base image that is pulled in as the foundation for creating your own custom images. Rather than just being reactive to new vulnerabilities, it is advisable to take a proactive approach by starting with a set of base images that are well-curated and continually updated.

In this post, we look at Red Hat Universal Base Images which helps with the objective outlined above.

What is Universal Base Image (UBI)?

Announced at the Red Hat Summit in 2019, Red Hat Universal Base Images are built on an enterprise grade platform, Red Hat Enterprise Linux (RHEL). The images are OCI-compliant container base operating system images with a variety of runtime languages and packages that are freely redistributable. These images for UBI 8, for instance, are updated every time RHEL 8 base images are updated and when critical CVEs are patched.

From a technical perspective, they are nearly identical to Red Hat Enterprise Linux images, which means they have great security, performance, and life cycles. They are released under a different End User License Agreement --It’s possible to build a containerized application using UBI, push it to any registry server, easily share it with others — and because it’s freely redistributable — even deploy it on non-Red Hat platforms.

Complete details are available in Red Hat's documentation on Building, Running, And Managing Containers. Certified container images are also listed in Red Hat’s container catalog. The UBI images cover a wide array of popular development languages, including dotnet, golang, nodejs, Python, PHP and Ruby.

You can find additional information on UBI images in Red Hat's FAQ, but it’s fairly easy to incorporate UBI images while maintaining your workflow as we show below.

Building container images using UBI

Let’s start with a Dockerfile example for Python. it’s possible to use UBI images for different language runtimes based on a similar approach.

Here’s an auto-generated Dockerfile for a simple Python “Hello World!” example that uses flask.

1FROM python
2ENV PORT 8080
3EXPOSE 8080
4WORKDIR /usr/src/app
5
6COPY requirements.txt . 
7RUN pip install --no-cache-dir -r requirements.txt
8
9COPY . .
10
11ENTRYPOINT ["python"] 
12CMD ["app.py"]

Instead of using python as the base image, let’s use the UBI image from the Red Hat registry by modifying the Dockerfile as below (you may need the right credentials to be able to authenticate and use the images). Notice the only change is in the first line where we use the UBI image.

1FROM registry.redhat.io/ubi8/python-36
2ENV PORT 8080
3EXPOSE 8080
4WORKDIR /usr/src/app
5
6COPY requirements.txt ./
7RUN pip install --no-cache-dir -r requirements.txt
8
9COPY . .
10
11ENTRYPOINT ["python"] 
12CMD ["app.py"]

Generating a containerized app with UBI as the base image is identical to generating with a non UBI image as below:

1docker build -t ragsns/example-python-ubi .

Running snyk on the containerized app with UBI as the base image generates a list of vulnerabilities as shown below.

1snyk test --container ragsns/example-python-ubi --file=Dockerfile          
2
3Testing ragsns/example-python-ubi...
4
5✗ Low severity vulnerability found in npm
6  Description: RHEA-2020:0330
7  Info: https://snyk.io/vuln/SNYK-RHEL8-NPM-555355
8  Introduced through: npm@1:6.9.0-1.10.16.3.2.module+el8.0.0+4214+49953fda
9  From: npm@1:6.9.0-1.10.16.3.2.module+el8.0.0+4214+49953fda
10  Introduced by your base image (registry.redhat.io/ubi8/python-36)
11  Fixed in: 1:6.13.4-1.12.14.1.1.module+el8.1.0+5466+30f75629
12
13Low severity vulnerability found in nodejs
14  Description: RHEA-2020:0330
15  Info: https://snyk.io/vuln/SNYK-RHEL8-NODEJS-555347
16  Introduced through: nodejs@1:10.16.3-2.module+el8.0.0+4214+49953fda
17  From: nodejs@1:10.16.3-2.module+el8.0.0+4214+49953fda
18  Introduced by your base image (registry.redhat.io/ubi8/python-36)
19  Fixed in: 1:12.14.1-1.module+el8.1.0+5466+30f75629
20
21High severity vulnerability found in systemd-pam
22  Description: RHSA-2020:0575
23  Info: https://snyk.io/vuln/SNYK-RHEL8-SYSTEMDPAM-552042
24  Introduced through: systemd-pam@239-18.el8_1.2
25  From: systemd-pam@239-18.el8_1.2
26  Introduced by your base image (registry.redhat.io/ubi8/python-36)
27  Fixed in: 0:239-18.el8_1.4
28
29High severity vulnerability found in systemd-libs
30  Description: RHSA-2020:0575
31  Info: https://snyk.io/vuln/SNYK-RHEL8-SYSTEMDLIBS-552044
32  Introduced through: systemd-libs@239-18.el8_1.2
33  From: systemd-libs@239-18.el8_1.2
34  Introduced by your base image (registry.redhat.io/ubi8/python-36)
35  Fixed in: 0:239-18.el8_1.4
36
37High severity vulnerability found in systemd
38  Description: RHSA-2020:0575
39  Info: https://snyk.io/vuln/SNYK-RHEL8-SYSTEMD-552048
40  Introduced through: systemd@239-18.el8_1.2
41  From: systemd@239-18.el8_1.2
42  Introduced by your base image (registry.redhat.io/ubi8/python-36)
43  Fixed in: 0:239-18.el8_1.4
44
45High severity vulnerability found in npm
46  Description: RHSA-2020:0579
47  Info: https://snyk.io/vuln/SNYK-RHEL8-NPM-555375
48  Introduced through: npm@1:6.9.0-1.10.16.3.2.module+el8.0.0+4214+49953fda
49  From: npm@1:6.9.0-1.10.16.3.2.module+el8.0.0+4214+49953fda
50  Introduced by your base image (registry.redhat.io/ubi8/python-36)
51  Fixed in: 1:6.13.4-1.10.19.0.1.module+el8.1.0+5726+6ed65f8c
52
53High severity vulnerability found in npm
54  Description: RHSA-2020:0598
55  Info: https://snyk.io/vuln/SNYK-RHEL8-NPM-557042
56  Introduced through: npm@1:6.9.0-1.10.16.3.2.module+el8.0.0+4214+49953fda
57  From: npm@1:6.9.0-1.10.16.3.2.module+el8.0.0+4214+49953fda
58  Introduced by your base image (registry.redhat.io/ubi8/python-36)
59  Fixed in: 1:6.13.4-1.12.16.1.1.module+el8.1.0+5811+44509afe
60
61High severity vulnerability found in nodejs
62  Description: RHSA-2020:0579
63  Info: https://snyk.io/vuln/SNYK-RHEL8-NODEJS-555367
64  Introduced through: nodejs@1:10.16.3-2.module+el8.0.0+4214+49953fda
65  From: nodejs@1:10.16.3-2.module+el8.0.0+4214+49953fda
66  Introduced by your base image (registry.redhat.io/ubi8/python-36)
67  Fixed in: 1:10.19.0-1.module+el8.1.0+5726+6ed65f8c
68
69High severity vulnerability found in nodejs
70  Description: RHSA-2020:0598
71  Info: https://snyk.io/vuln/SNYK-RHEL8-NODEJS-557034
72  Introduced through: nodejs@1:10.16.3-2.module+el8.0.0+4214+49953fda
73  From: nodejs@1:10.16.3-2.module+el8.0.0+4214+49953fda
74  Introduced by your base image (registry.redhat.io/ubi8/python-36)
75  Fixed in: 1:12.16.1-1.module+el8.1.0+5811+44509afe
76
77Organization:      rags
78Package manager:   rpm
79Target file:       Dockerfile
80Project name:      docker-image|ragsns/example-python-ubi
81Docker image:      ragsns/example-python-ubi
82Base image:        registry.redhat.io/ubi8/python-36
83Licenses:          enabled
84
85Tested 417 dependencies for known issues, found 9 issues.

Running the UBI-based container image is also identical to running the application based on the non-UBI image as shown below.

1docker run -it -p8080:8080 ragsns/example-python-ubi
2

This is possible based on what is outlined in the documentation “The new Red Hat Universal Base Images enable you to build your container ONCE and freely redistribute it to multiple deployment platforms.”

Or, if you prefer to use Red Hat’s container toolset for testing or running the application, you can use the following command

1podman run -p 8080:8080 ragsns/example-python-ubi
2

Now that we’ve seen a Python language example, rather than walk through each of the language runtime examples individually (and there may be some more minor changes required for working with the respective language runtime), let’s take a collective look at all of them.

UBI images for multiple languages

As indicated earlier, there are UBI images for multiple language runtimes. Running Snyk on the different UBI images produces an output that is summarized in the following table.

UBI Image

Dependencies

Vulnerabilities

registry.redhat.io/ubi8/nodejs-10

373

9

registry.redhat.io/ubi8/python-36

417

9

registry.redhat.io/ubi8/ruby-26

481

9

registry.redhat.io/ubi8/php-73

403

9

registry.redhat.io/ubi8/go-toolset

371

13

registry.redhat.io/ubi8/dotnet-21

248

10

The UBI images for the variety of languages and the low vulnerability count is as a result of Red Hat carefully curating and updating them, including the base operating system, the yum repositories used to install packages and tools, and the languages and frameworks.  This Red Hat article goes into detail, primarily by maintaining a bug list of the UBI images and how they are periodically refreshed and maintained in a process similar to what is used for the base operating system itself.

Summary and next steps

We’ve shown how easy it is to base containerized applications on UBI images for multiple language runtimes. The changes including pulling the Red Hat UBI image is fairly easy to apply and incorporate into your CI/CD or development pipeline and continue to maintain normal workflows.

From a security perspective, UBI images are a good option for containerizing your applications since we’ve seen how the UBI images follow a rigorous maintenance process, in-line with the well-established process for the RHEL operating system . Since UBI images are available for a variety of language runtimes, using them as a base image for your containerized images will help minimize vulnerabilities in your application.

Snyk supports the security of your application development for the entire software development lifecycle, including integrations with your image registry, Dockerfile repository, CI/CD pipelines, and Kubernetes clusters, including OpenShift 4 environments. Snyk Container supports UBI and RHEL images as well as other popular Linux distros.

Developer-First Security für Container

Mit Snyk identifizieren Sie Schwachstellen in Container-Images und Kubernetes-Workloads und adressieren sie automatisch.