You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/pentesting-cloud/kubernetes-security/kubernetes-basics.md
+76Lines changed: 76 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -364,6 +364,75 @@ helm search <keyword>
364
364
365
365
Helm is also a template engine that allows to generate config files with variables:
366
366
367
+
### Helm `.Values` YAML injection
368
+
369
+
If a chart inserts **attacker-controlled values** directly into YAML, Helm will **render them as raw YAML content** unless the template explicitly quotes, converts, or validates them. This is especially dangerous in **GitOps** environments (for example with **ArgoCD**) where developers are only allowed to modify `values.yaml` and the chart is assumed to be trusted.
If an attacker can control those values, they can abuse YAML multiline scalars (`|` or `|-`) to **break the expected context**, inject **new fields** at the right indentation level, and even inject **new YAML documents** with `---`.
381
+
382
+
### Exploitation ideas
383
+
384
+
-**Field injection** from scalar-looking values:
385
+
386
+
```yaml
387
+
replicaCount: |
388
+
3
389
+
injectedAttribute: true
390
+
```
391
+
392
+
This can transform a numeric-looking field into additional manifest attributes.
393
+
394
+
- **Quoted-context breakout** to inject container attributes such as `command`, `args`, or `securityContext`:
395
+
396
+
```yaml
397
+
image:
398
+
tag: |-
399
+
1.0.0"
400
+
securityContext:
401
+
privileged: true
402
+
command: ["/bin/sh", "-c"]
403
+
args: ["id"]
404
+
```
405
+
406
+
- **Arbitrary object injection** by creating extra YAML documents with `---`, which may create resources such as `Namespace`, `Pod`, `Role`, `ClusterRole`, `RoleBinding`, or `ClusterRoleBinding` if the Helm/ArgoCD service account is allowed to create them. This connects directly with [RBAC abuse](kubernetes-role-based-access-control-rbac.md), [abusing dangerous roles](abusing-roles-clusterroles-in-kubernetes/), and [namespace pivoting](kubernetes-namespace-escalation.md).
407
+
408
+
> [!WARNING]
409
+
> Control over `values.yaml` in a vulnerable chart can become **arbitrary workload creation**, **command execution inside Pods**, **privileged Pod deployment**, and sometimes **cluster compromise**.
410
+
411
+
### Helm v3 vs Helm v4
412
+
413
+
- **Helm v3** may accept injected unknown fields as long as the final rendered output is valid YAML.
414
+
- **Helm v4** uses **Server-Side Apply** by default and rejects several invalid fields against the Kubernetes schema.
415
+
- However, **Helm v4 does not fully solve the problem**: an attacker may still inject **valid resources first** and append a final invalid object only to absorb the broken context, so previously injected valid resources are still created.
{{- if not (regexMatch "^(latest|1\.1|dev)$" .Values.image.tag) }}
425
+
{{- fail "invalid image.tag" }}
426
+
{{- end }}
427
+
```
428
+
429
+
Additional hardening:
430
+
431
+
- Use `values.schema.json` to enforce **types**, **required keys**, and **regex patterns** during `helm template`, `helm install`, `helm upgrade`, and `helm lint`.
432
+
- In **ArgoCD**, restrict the kinds an application can create via `AppProject` rules such as `clusterResourceWhitelist`, and prefer **namespace-scoped** ArgoCD permissions whenever possible.
433
+
- Use **ValidatingAdmissionPolicy** / **ValidatingAdmissionPolicyBinding**, Kyverno, or Gatekeeper rules to block dangerous outputs such as **privileged Pods** even if rendering was compromised.
434
+
- If a target namespace is protected by Pod Security controls, check whether the attacker can inject a **new namespace** where those controls do not apply, then use the new workload for [pod escape](abusing-roles-clusterroles-in-kubernetes/pod-escape-privileges.md) or further [post-compromise attacks from inside a pod](attacking-kubernetes-from-inside-a-pod.md).
435
+
367
436
## Kubernetes secrets
368
437
369
438
A **Secret** is an object that **contains sensitive data** such as a password, a token or a key. Such information might otherwise be put in a Pod specification or in an image. Users can create Secrets and the system also creates Secrets. The name of a Secret object must be a valid **DNS subdomain name**. Read here [the official documentation](https://kubernetes.io/docs/concepts/configuration/secret/).
@@ -564,6 +633,13 @@ https://sickrov.github.io/
564
633
https://www.youtube.com/watch?v=X48VuDVv0do
565
634
{{#endref}}
566
635
636
+
- [Charting your way in: Helm template injection](https://synacktiv.com/en/publications/charting-your-way-in-helm-template-injection.html)
637
+
- [Helm template functions and pipelines](https://helm.sh/docs/chart_template_guide/functions_and_pipelines/)
- [Argo CD projects (`AppProject` restrictions)](https://argo-cd.readthedocs.io/en/latest/user-guide/projects/)
640
+
- [Argo CD multiple sources / external Helm value files](https://argo-cd.readthedocs.io/en/latest/user-guide/multiple_sources/#helm-value-files-from-external-git-repository)
0 commit comments