What’s the correlation between Kubernetes and software supply chains? To answer that question, let’s start by exploring the latter. Simply put, software supply chains are the lifeblood of building, delivering, maintaining and scaling cloud-native applications. They are made up of software components, including those at the infrastructure and application layer, and their underlying pipelines, repositories and registries.
Securing supply chains starts with an understanding of the risks facing each component. Here are some examples of Kubernetes risks at each stage of the development life cycle:
- Code: Misconfigurations within the infrastructure-as-code (IaC) incarnations of Kubernetes such as manifests, Helm charts, Kustomize files or Dockerfiles, as well as vulnerable open source packages used by application code such as Python, Node.js and Go.
- Build: Insecure configurations of version control systems and repositories used to build, store and manage Kubernetes code, malicious images that can introduce vulnerabilities and malicious process execution at runtime and exposed secrets.
- Deploy: CI/CD pipelines without the proper access control and configuration that allow compromise of otherwise secure Kubernetes components and image poisoning that can unknowingly introduce malware into a cluster.
- Run: Overly permissive access that can amplify the impact of a compromised pipeline or stolen credentials and external abuse of admin roles and out-of-band changes that can result in misconfigurations or vulnerabilities that can lead to a breach.
Within cloud-native applications, those components are intentionally distributed but inextricably linked, creating complex chains of dependencies. As a result, just one weakness in any component can give attackers access to proprietary code. Worse, by stringing together multiple weaknesses, they can pivot to exfiltrate data, insert malicious code or deploy resource-sucking cryptominers.
A comprehensive Kubernetes security strategy is required to keep those individual and chained risks at bay. Here are five tips for securing your cloud-native software supply chain.
1. IaC misconfigurations
One of the great benefits of Kubernetes is its compatibility with infrastructure as code. Using Kubernetes manifests, Helm charts, or Kustomize files, developers can define how containers and clusters will be deployed with code. Unfortunately, misconfigurations in code are extremely easy to miss and can create weaknesses across different components of your Kubernetes pods, containers, and APIs.
For example, a missing or incorrect value within Kubernetes code may result in:
- Privilege escalation in containers
- Unencrypted internal traffic between your API server and kubelets
- Containers escalated to privileged mode
- And many, many others
Kubernetes’ machine readability also makes it easier to identify misconfigurations earlier in the DevOps life cycle. You can check for misconfigurations using open source IaC scanners such as Checkov, which you can use from the command line, via IDE extensions, as part of your CI/CD pipeline and as an admission controller.
2. Container misconfigurations and vulnerabilities
Containers blur the line between application and infrastructure and can contain both misconfigurations and vulnerabilities. They are created from configuration files such as Dockerfiles and include packages that need to be configured to meet the need of the service.
From a software supply chain security perspective, containers add complexity in that they enable microservices for independent, decoupled development and span across multiple layers of a stack. For example, an application may be secure, but data can be exfiltrated if a firewall rule leaves the front door open. Similarly, if the infrastructure is fully locked down, but a vulnerability with a public rootkit exists in the front end of a web service, attackers can easily inject malicious code.
That’s why it’s essential to have a complete picture of your security posture, from the infrastructure to the containers running on top. The best time to secure a container is during the development and build phases. You can run scanners on individual images directly from the command line, automatically for images in registries and at runtime for running containers.
3. Insecure third-party components
Cloud-native applications rely heavily on third-party components, making us highly dependent on the goodwill of maintainers and their security adeptness. This shouldn’t surprise anyone, but it doesn’t make it any less important or prevalent. When analyzing publicly available Helm charts, we found that 71% contained at least one misconfiguration and 99% contained a vulnerability.
Relying on Helm charts that contain misconfigurations or container images with security vulnerabilities can compromise the security of your supply chain. Similarly, when pulling Kubernetes container images from a registry, it’s important to keep security best practices in mind. Simple gotchas like pulling the “latest” version can make it harder to know the exact version you’re using—and, by extension, harder to know if they contain vulnerabilities or malware.
The use of third-party components isn’t going away anytime soon. Thus it’s the developers’ responsibility to bake in security best practices such as those we’ve covered so far when leveraging open source.
4. Weaknesses within delivery pipeline configurations
Your Kubernetes code, containers, pods and clusters are only as secure as the pipelines and processes employed to deliver, deploy and manage them.
A sometimes overlooked aspect of cloud-native risk is your VCS (sometimes referred to as an SCM), such as GitHub, GitLab, or Bitbucket. For larger enterprises, especially, it’s crucial to enable two-factor authentication (2FA) and SSO and define an IP allowlist for Git users to prevent unauthorized access when configuring VCS org settings. Without the proper access controls and branch protection rules, a misconfigured VCS repository can be the perfect starting point for a supply chain attack.
Similarly, CI/CD pipelines play a vital role in delivering and deploying code and thus also need to be hardened. Unvetted changes to workflow files made by internal or external malicious actors can lead to shell injections sourced in build triggers and the execution of deprecated and insecure commands. Scanning CI/CD workflow files and ensuring minimal access is allowed to run tests and deploy updates are best practices to follow.
5. Lack of visibility
Lastly, it wouldn’t be a true supply chain or Kubernetes post without the mention of the SBOM or software bill of materials. SBOMs seem to be popping up left and right—and for good reason. If you don’t have visibility into the components of your supply chain, you can’t secure them. Building an SBOM using the most popular formats, CycloneDX and SPDX, is a great place to start getting an inventory of all first-party and third-party components for risk assessment.
A complete SBOM should contain all direct and transitive components and the dependency relationships between them, including software components such as containers, libraries, files and OSes, as well as being capable of describing external services such as microservice architectures. Using CycloneDX or SPDX, your SBOM will also give you an inventory of known vulnerabilities and their exploitability.
With the rise of distributed development technologies and methodologies such as infrastructure-as-code, Kubernetes and containers, cloud-native supply chains are more complex than ever. By looking at the individual components of supply chains and the interactions between them, we can gain better visibility into our weaknesses and an understanding of how to prioritize the ever-present risks.
This post originally appeared as a Security Boulevard post.