The recent buzz surrounding the actively exploited runc vulnerabilities “Leaky Vessels” (CVE-2024-21626) serves as a timely reminder of two essential container security principles: image trust and comprehensive patching. Let’s delve into why these aspects are crucial for your containerized environments.
- Trustworthy Images are Foundational: It might seem self-evident, but avoiding untrusted images is paramount. My experience conducting Kubernetes security reviews highlights this as the most frequent pitfall. In the context of the runc vulnerability, pulling an image from an unreliable source could grant attackers a direct entry point into your Kubernetes cluster. Remember, the attack surface expands with every untrusted image you incorporate.
- Patching Permeates the Entire Stack: While patching container orchestration platforms like Kubernetes is expected, don’t neglect low-level components like runc. Often overlooked due to their seemingly insignificant nature, these pieces play a critical role. In this case, runc establishes and executes the container sandbox, making its security integral. Leaving it unpatched creates a gaping hole in your defenses, nullifying the effectiveness of security measures applied elsewhere.
Adhering to these fundamental principles can significantly strengthen your container security posture. Scrutinize image sources meticulously and prioritize patching across your container ecosystem, from high-level platforms to foundational components like runc. Remember, a chain is only as strong as its weakest link. Don’t let a seemingly minor vulnerability become your downfall.
Suppose you are a Nirmata customer running Nirmata Control Hub or running Kyverno in production. In that case, you can use the following policy to understand better how impactful this new vulnerability will be.
The policy will check your container runtimes for the vulnerable versions and produce an actionable report:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: check-container-run-time
spec:
validationFailureAction: Audit
background: true
rules:
- name: container-run-time-version
match:
any:
- resources:
kinds:
- Node
context:
- name: cr_version
variable:
jmesPath: split(request.object.status.nodeInfo.containerRuntimeVersion, '://')[1]
- name: cr_runtime
variable:
jmesPath: split(request.object.status.nodeInfo.containerRuntimeVersion, '://')[0]
validate:
message: "Your container runtime is vulnerable to CVE-2024-21626 & CVE-2024-23651: {{cr_runtime}}:{{cr_version}}"
deny:
conditions:
any:
- key: |-
{{ cr_runtime == 'containerd' && semver_compare(cr_version, '<= 1.6.27') || false }}
operator: Equals
value: true
- key: |-
{{ cr_runtime == 'runc' && semver_compare(cr_version, '<= 1.1.11') || false }}
operator: Equals
value: true
Furthermore, you can detect containers trying to exploit the vulnerability by mounting /proc/self/fd/*. Note that it is recommended that you run the policy in Audit mode prior to Enforce mode, as potential false positives are expected.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-proc-self-fd-workingdir
spec:
validationFailureAction: Enforce
background: true
rules:
- name: no-proc-self-fd-images
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Mounting /proc/self/fd is not allowed CVE-2024-21626."
pattern:
spec:
containers:
- =(workingDir): "!/proc/self/fd*"
=(initContainers):
- =(workingDir): "!/proc/self/fd*"
=(ephemeralContainers:
- =(workingDir): "!/proc/self/fd*"
You can use the following to block persons from blatantly trying to exploit Leaky Vessels. It will not be able to detect a container that has hidden its attempts to abuse the vulnerability deeper in its code; the scope of detection of such an attack is beyond Kyverno.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: block-proc-self
spec:
validationFailureAction: Enforce
background: false
rules:
- name: container-exec-block-proc-self
match:
any:
- resources:
kinds:
- Pod/exec
validate:
message: "Pod {{ request.object.metadata.namespace }}/{{ request.object.metadata.name }} cannot use /proc/self/cwd, CVE-2024-21626"
deny:
conditions:
any:
- key: "{{ request.object.spec.containers[].args[] | contains(@, '/proc/self/cwd') }}"
operator: Equals
value: true
- key: "{{ request.object.spec.initContainers[].args[] | contains(@, '/proc/self/cwd') }}"
operator: Equals
value: true
- key: "{{ request.object.spec.ephemeralContainers[].args[] | contains(@, '/proc/self/cwd') }}"
operator: Equals
value: true
- key: "{{ request.object.command | contains(@, '/proc/self/cwd') }}"
operator: Equals
value: true
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: block-proc-self-mounting
spec:
validationFailureAction: Enforce
rules:
- name: no-proc-self-images
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Pod {{ request.object.metadata.namespace }}/{{ request.object.metadata.name }} with images having /proc/self/fd/ in their layers are not allowed CVE-2024-21626."
foreach:
- list: "request.object.spec.containers"
context:
- name: imageData
imageRegistry:
reference: "{{ element.image }}"
deny:
conditions:
any:
- key: "{{ imageData.configData.history[].created_by | contains(@, '/proc/self/fd/') }}"
operator: Equals
value: true
- list: "request.object.spec.initContainers"
context:
- name: imageData
imageRegistry:
reference: "{{ element.image }}"
deny:
conditions:
any:
- key: "{{ imageData.configData.history[].created_by | contains(@, '/proc/self/fd/') }}"
operator: Equals
value: true
- list: "request.object.spec.ephemeralContainers"
context:
- name: imageData
imageRegistry:
reference: "{{ element.image }}"
deny:
conditions:
any:
- key: "{{ imageData.configData.history[].created_by | contains(@, '/proc/self/fd/') }}"
operator: Equals
value: true
Beyond Trust, Verify: Securing the Container Supply Chain with Signing
Container image signing plays a crucial role in ensuring the authenticity and integrity of the code within your containerized applications. It works like a digital fingerprint, allowing you to verify that the image you’re deploying hasn’t been tampered with or modified. This explicitly blocks potential vulnerabilities such as Leaky Vessel by ensuring you never execute unknown code.
Benefits
- Increased security: Signing helps prevent attackers from injecting malicious code into your images, potentially compromising your entire system.
- Enhanced trust: Signing verifies the image’s origin and publisher, ensuring you’re deploying what you intended.
- Improved compliance: Some industries and regulations mandate signed images for security and audit purposes.
- Reduced risk: Identifying and mitigating vulnerabilities becomes easier when you know precisely what code you’re running.
Mechanisms
- Signing Key Pair: You obtain a signing key pair with a private key (kept secret) and a public key (distributed).
- Signing the Image: The private key is used to sign the container image cryptographically, creating a signature.
- Verifying the Signature: The public key and signature confirm that the image hasn’t been altered on deployment.
Popular Tools
- Cosign: An open-source tool based on the Sigstore standard, supporting keyless signing and various signing authorities.
- Notary: An integrated solution from Docker for signing and verifying images within their ecosystem.
- AWS Signer: A managed service from AWS for signing images stored in their Elastic Container Registry (ECR).
- Venafi CodeSign Protect: A managed X.509 and HSM service with enterprise-grade signing and verification.
Tie It All Together
If you do nothing else, please consider:
- Scan your nodes for vulnerable runc versions: Use the provided Kyverno policy to identify nodes running vulnerable versions of containerd or runc (CVE-2024-21626 & CVE-2024-23651). Patch affected nodes immediately.
- Audit your deployments for suspicious container behavior: Implement the Kyverno policy to detect containers attempting to mount /proc/self/fd/*, the technique used in the Leaky Vessels exploit. Run it in audit mode first to identify potential false positives.
- Block execution of untrusted images: Enforce the Kyverno policy that checks for images containing /proc/self/fd/ in their layers, which could potentially indicate tampering.
For long-term security, use Nirmata Control Hub and Kyverno together to offer robust image security integrations, providing you with the ability to:
- Implement image signing and verification: This ensures the authenticity and integrity of your container images, preventing vulnerabilities like Leaky Vessels. Consider tools like Cosign, Notary, AWS Signer, or Venafi CodeSign Protect.
- Prioritize image trust: Only pull images from trusted sources and registries. Avoid untrusted images to minimize the attack surface.
- Maintain comprehensive patching: Patch not just Kubernetes but also low-level components like runc. A chain is only as strong as its weakest link.
- Use Nirmata Control Hub: Leverage these tools to enforce security policies and automate vulnerability detection and mitigation.
To manage policies and governance easily across multiple clusters, check out what Nirmata is building at https://nirmata.com/.
Sorry, the comment form is closed at this time.