Detect vulnerabilities in container images and take action

Get the code

The innovation of tools and technology for developers over the past few years has led to a plethora of choices and options for ideating solutions. However, even with advances in our tool stack, we still must be conscious of secure engineering practices, including limiting attack vectors. It sounds simple, but in actuality, for production-level software and any modern software, we face any of the following possible attack vectors:

  • Operating system (OS) vulnerabilities: unpatched libraries and OS components, vulnerable kernel versions, and vulnerable network library versions.
  • Configuration vulnerabilities: nonsecure OS settings, such as passwords or logins as well as network configuration, including allow root, no whitelisting of IPs, and lack of Secure Shell (SSH).
  • Application weaknesses: XSS, buffer overloading, and SQL injection.

Containerization drastically improved how we can develop repeatable, reusable software. But a common concern still exists about how we can prevent passing on those threats to consumers of the containers. With containerization, this concern is magnified, because every layer in the container is just one link in the chain. The containers that you produce can be used as the base for another container, and so on, with every link in that chain susceptible to the attack vectors and threats.

This code pattern includes example code for using the application programming interface (API) for the Vulnerability Advisor, a powerful service within the IBM Cloud Container Registry that ensures and maintains the security of containers. The Vulnerability Advisor scans layers and configuration of a Docker image and can detect image and configuration vulnerabilities for anything in the registry, as well as images currently running. The goal of this code pattern is to make this data available and actionable.

Description

This code pattern demonstrates how to use the Vulnerability Advisor APIs retrieve and process real-time results for containers that are scanned. This information is displayed in a dashboard sample application that makes use of the Vulnerability Advisor APIs, showing how to interact with the APIs and perform actions based on data from the Vulnerability Advisor service.

For general information, see the Vulnerability Advisor documentation. In addition, for more information about using the API, see Vulnerability Advisor API documentation.

When containers are loaded into the IBM Cloud Container Registry service, they are automatically scanned by the Vulnerability Advisor (although you can initiate an assessment through the API if you want). You can retrieve data from these scans in several ways.

Account data available from the Vulnerability Advisor APIs provides vital assessment information for an IBM Cloud account. Your IBM Cloud account is used to upload images to the container registry and you can view those assessments as an aggregate from the account view. This view helps you group and list all owned images for the account. For each image, you can create a link to a dashboard for a specific image (the link the user of the app selects) where more detail assessment information is presented for that specific image.

The GET /va/api/v3/report/account API returns the vulnerability assessment for all resources in the account. The return data for this API can consist of several assessments (one for each container or image owned by the account). This assessment consists of the following data:

  • Configuration issues identified, such as corrective actions needed, description of the issue, if the issue is exempt according to defined policies, and the type of check the issue failed.
  • The ID of the assessment.
  • A timestamp for the scan of the image.
  • A list of Common Vulnerabilities and Exposures (CVE) that are identified for the image: whether it is exempt, the CVE ID, security notice information, and a summary of the vulnerability.
  • An overall status of the image based on vulnerabilities, identified configuration issues, and applied exemptions.

For this sample code, the ID, scan timestamp, and overall status is presented in the dashboard.

Similar to the report/account API, GET /va/api/v3/report/account/status returns useful cumulative assessment results for the images owned by the account for each image. You pull the results into the sample dashboard app. The results include numbers of the following issues:

  • Issues found
  • Exempt issues found
  • Vulnerabilities
  • Exempt vulnerabilities
  • Configuration issues
  • Exempt configuration issues

The Vulnerability Advisor APIs provide more detailed information for container images that can give a deeper understanding of an image and its use. This data is used to drill down into an image that the user of the app selects from the dashboard.

GET /va/api/v3/exemptions/image/{resource} returns a list of all the exemptions in effect for an image. Exemptions are vulnerabilities that can be identified when found in a scan by the Vulnerability Advisor. They do not affect the assessment status, because they are not applicable or critical as a hypothetical example. There are two ways to create exemptions: exemptions that apply to a specific image (which are returned by this API) and exemptions that apply to all images in an account (see the next API call).

The GET /va/api/v3/exempt/image API returns a list of all exemptions defined at the account level for all images owned by the account. The returned data includes:

  • Account ID
  • Issue ID
  • Issue type

GET /va/api/v3/report/image/{name} returns the vulnerability assessment for the image specified. The data that is returned is similar to the account assessment previously described, but for a specific image, so only one assessment is returned. GET /va/api/v3/report/image/{name} and GET /va/api/v3/report/account share the same assessment data.

GET /va/api/v3/report/image/status/{name} is similar to the aggregate vulnerability status returned for an account, except the scope for this API is for the image that is specified in the API call. The returned data is similar to the assessment data captured from GET /va/api/v3/report/account/status. Again, only a single row of aggregate data is returned.

GET /va/api/v3/report/image/{name}/containers returns the list of images that are running as instantiated containers owned and created by the account. The data returned for this call consists of data to help identify the pods and runtime locations of the container images:

  • Ancestor name
  • Ancestor type
  • Cluster
  • ID
  • Name
  • Pod

The APIs from IBM Cloud that are used in this code pattern are protected by IBM’s authentication services that require the account ID and the authorization token as input parameters. The sample code shows using a sample account ID and retrieving the bearer token that uses ibmcloud iam oauth-tokens. Implement more robust solutions for production environments.

Flow

The dashboard sample app assumes that some containers were submitted to the container registry and that the Vulnerability Advisor assessments have been completed.

  1. The dashboard consists of two parts. The first part is the main dashboard that makes two API calls to the Vulnerability Advisor APIs: /va/api/v3/report/account and /va/api/v3/report/account/status.

  2. These APIs return an aggregate of container status and vulnerabilities for all containers owned by the account. The dashboard iterates through each image returned in the list and display the corresponding information. Each image is built as a link to the container details page.

  3. If the users of the app select an image link from the dashboard they are sent to a page for details about the selected container using the following API calls:

    • /va/api/v3/exemptions/image/{resource}
    • /va/api/v3/exempt/image
    • /va/api/v3/report/image/{name}
    • /va/api/v3/report/image/status/{name}
    • /va/api/v3/report/image/{name}/containers

Vulnerability Advisor Assessment Dashboard app for containers

Instructions

Ready to try this code pattern? Get the detailed instructions in the README file.

  1. Clone the repo.
  2. Retrieve the oauth token and log in.
  3. Complete additional configuration steps.
  4. Run the app, and go to the top directory to run node app.js.