Checkov 2.0: Deeper, broader, and faster IaC scanning

With the pull request open for the past week for final testing and feedback, we’ve now merged the first 2.x version of Checkov! Checkov is the most popular open-source scanner for infrastructure as code (IaC), and with the launch of Checkov 2.0, it’s the first to have dependency awareness.

Checkov 2.0 has full backward compatibility for everyone running Checkov-enabled CI pipelines and contains several core additions based on over a year of gathering community development and industry feedback.

  1. We’ve completely rearchitected the Terraform scanning backend to be graph-based. This allows for multi-resource queries with improved variable resolution and drastically increases performance.
  2. Checkov can now scan Dockerfiles for deeper build-time coverage.
  3. We’ve added nearly 250 new out-of-the-box policies.

New graph-based policies

The biggest change in Checkov 2.0 is the replacement of our Terraform processing logic with a graph-based framework. The TL;DR for finding security issues in Terraform with Checkov 2.0 with our new-and-improved framework is this:

  • Graphs allow us to render variables for Terraform (and module inheritance) a lot more efficiently.
  • Graphs allow us to ask more complex questions about our infrastructure as code templates, taking into account the context of the environment, rather than just the individual resources’ attributes.
  • Graphs provide performance improvements over Checkov 1.0.

With a graph of interconnected nodes and edges, Checkov can now ask questions that require context from more than one resource.

Take this example EC2 instance from our training repo TerraGoat:

How do we know if it’s accessible from the public internet? Nothing in the definition of the EC2 instance in Terraform itself can categorically answer the question. So to understand the context for this instance, we need to understand what other objects it’s attached to or supported by. For example, which VPC and security group(s) is the instance attached to?

Enter Checkov 2.0, which builds an internal representation (or graph) of all the attached adjacent objects. Our example’s adjacencies are mapped out in the diagram below. We can see that all the objects in red have a part to play in whether the instance may be publicly accessible.

New policies in Checkov 2.0 make use of this graph, providing a simple query language across these adjacencies. We can now ask such questions as “Is this EC2 instance public?” or “Does this instance have any snapshots which are not encrypted?”

To do this, we’ve created a simple yet powerful policy definition language, written in YAML, supporting the following constructs:

  • equals / not equals
  • exists / not exists
  • starting_with / not_starting_with
  • ending_with / not_ending_with
  • contains / not contains (for lists and strings)
  • connection_exists / connection_not_exists
  • and / or complex query (for attributes and for different predicates)
  • within filtering

Graph-based policies take on a new CKV2_ naming scheme for easy differentiation with existing CKV_ policies. Let’s jump into an example CKV2_ policy already built into Checkov 2.0 to demonstrate some of these constructs:

Here we can see the tree structure of a YAML-based policy. We have a policy to ensure that no Amazon EMR cluster is exposed to the public internet. Instead of just failing on a security group containing 0.0.0.0/0, we can use the graph’s context to identify which cluster is exposed. This shifts the focus onto the instances themselves rather than dealing with lists of tens (or thousands) of security groups.

YAML-based policies allow Checkov to distill complex, multi-object queries into simple Checkov results. By putting the most important objects (EC2 instances, clusters, containers) at the forefront of the output for prioritization of risk, Checkov makes it simpler to delineate between perceived and actual risk.

Dockerfile support

Many Kubernetes IaC projects also contain Dockerfiles for building the application containers in the same git repository. Checking both Kubernetes manifests and Dockerfiles simultaneously for misconfigurations provides an added layer of protection against runtime security issues.

As is true for our other supported frameworks, Checkov will, by default, find relevant files and scan them. Here we see Docker issues in the results:

​Out of the box, Dockerfile support contains the following policies:

  • Ensuring that COPY is used instead of ADD in Dockerfiles.
  • Ensuring that HEALTHCHECK instructions have been added to container images.
  • Ensuring update instructions are not used alone in the Dockerfile.
  • Ensuring that a user for the container has been created
  • Ensuring port 22 is not exposed

As with all scans in Checkov, this is extensible to custom policies, and we’ll be adding new policies from our research team and the community.

Increased coverage

In this release, we’ve scoured the latest compliance benchmarks and improved coverage where possible. We’ve added nearly 250 new policies in both Python (CKV_) and graph (CKV2_) formats across multiple providers, as this breakdown shows:

Speaking of benchmarks, Checkov 2.0 also comes with some impressive performance improvements—runs were up to 65% quicker during testing. This is thanks in part to the graph-based Terraform logic that removes the need for multiple iterations over the provided IaC for variable resolution. A win-win!

Try it out!

To get the new version of Checkov, simply update your current environment

pip install checkov --upgrade
brew upgrade checkov

checkov --version
2.0.xx

Alternatively, pull the latest bridgecrewio/checkov Docker container:

docker pull bridgecrewio/checkov:latest

docker run bridgecrewio/checkov:latest  --version
2.0.xx

To hear more about this release, join us today for a very special community Office Hours and join in the conversation in the Codified Security Slack group.

Happy scanning!