Skip to content

Commit e405713

Browse files
authored
Merge pull request #317 from HackTricks-wiki/update_Charting_your_way_in_Helm_template_injection_c4c3d85e188cf37f
Charting your way in Helm template injection
2 parents 7c46190 + 12c5862 commit e405713

2 files changed

Lines changed: 79 additions & 8 deletions

File tree

src/pentesting-cloud/azure-security/az-privilege-escalation/az-automation-accounts-privesc.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ sudo nc -nlvp 443
314314

315315
The scheduled task executes the payload, achieving SYSTEM-level privileges.
316316

317-
{{#include ../../../banners/hacktricks-training.md}}
317+
318318

319319

320320
### `Microsoft.Automation/automationAccounts/python3Packages/write`, `Microsoft.Automation/automationAccounts/runbooks/write`, `Microsoft.Automation/automationAccounts/runbooks/publish/action`, `Microsoft.Automation/automationAccounts/jobs/write`
@@ -601,3 +601,4 @@ az rest --method GET \
601601
--url "https://management.azure.com/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.Automation/automationAccounts/${AUTOMATION_ACCOUNT}/jobs/${JOB_ID}/streams?api-version=2023-11-01"
602602
```
603603

604+
{{#include ../../../banners/hacktricks-training.md}}

src/pentesting-cloud/kubernetes-security/kubernetes-basics.md

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,75 @@ helm search <keyword>
366366
367367
Helm is also a template engine that allows to generate config files with variables:
368368
369+
### Helm `.Values` YAML injection
370+
371+
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.
372+
373+
**Typical vulnerable patterns:**
374+
375+
```yaml
376+
spec:
377+
replicas: {{ .Values.replicaCount }}
378+
...
379+
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
380+
```
381+
382+
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 `---`.
383+
384+
### Exploitation ideas
385+
386+
- **Field injection** from scalar-looking values:
387+
388+
```yaml
389+
replicaCount: |
390+
3
391+
injectedAttribute: true
392+
```
393+
394+
This can transform a numeric-looking field into additional manifest attributes.
395+
396+
- **Quoted-context breakout** to inject container attributes such as `command`, `args`, or `securityContext`:
397+
398+
```yaml
399+
image:
400+
tag: |-
401+
1.0.0"
402+
securityContext:
403+
privileged: true
404+
command: ["/bin/sh", "-c"]
405+
args: ["id"]
406+
```
407+
408+
- **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).
409+
410+
> [!WARNING]
411+
> Control over `values.yaml` in a vulnerable chart can become **arbitrary workload creation**, **command execution inside Pods**, **privileged Pod deployment**, and sometimes **cluster compromise**.
412+
413+
### Helm v3 vs Helm v4
414+
415+
- **Helm v3** may accept injected unknown fields as long as the final rendered output is valid YAML.
416+
- **Helm v4** uses **Server-Side Apply** by default and rejects several invalid fields against the Kubernetes schema.
417+
- 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.
418+
419+
### Defensive patterns
420+
421+
Treat every Helm value as **untrusted input**:
422+
423+
```yaml
424+
image: {{ printf "%s:%s" .Values.image.repository .Values.image.tag | quote }}
425+
replicas: {{ .Values.replicaCount | int }}
426+
{{- if not (regexMatch "^(latest|1\.1|dev)$" .Values.image.tag) }}
427+
{{- fail "invalid image.tag" }}
428+
{{- end }}
429+
```
430+
431+
Additional hardening:
432+
433+
- Use `values.schema.json` to enforce **types**, **required keys**, and **regex patterns** during `helm template`, `helm install`, `helm upgrade`, and `helm lint`.
434+
- In **ArgoCD**, restrict the kinds an application can create via `AppProject` rules such as `clusterResourceWhitelist`, and prefer **namespace-scoped** ArgoCD permissions whenever possible.
435+
- Use **ValidatingAdmissionPolicy** / **ValidatingAdmissionPolicyBinding**, Kyverno, or Gatekeeper rules to block dangerous outputs such as **privileged Pods** even if rendering was compromised.
436+
- 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).
437+
369438
## Kubernetes secrets
370439

371440
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/).
@@ -566,12 +635,13 @@ https://sickrov.github.io/
566635
https://www.youtube.com/watch?v=X48VuDVv0do
567636
{{#endref}}
568637
569-
{{#ref}}
570-
https://kubernetes.io/docs/concepts/storage/volumes/#image
571-
{{#endref}}
572-
573-
{{#ref}}
574-
https://kubernetes.io/docs/tasks/configure-pod-container/image-volumes/
575-
{{#endref}}
638+
- [Charting your way in: Helm template injection](https://synacktiv.com/en/publications/charting-your-way-in-helm-template-injection.html)
639+
- [Helm template functions and pipelines](https://helm.sh/docs/chart_template_guide/functions_and_pipelines/)
640+
- [Helm chart schema files (`values.schema.json`)](https://helm.sh/docs/topics/charts/#schema-files)
641+
- [Argo CD projects (`AppProject` restrictions)](https://argo-cd.readthedocs.io/en/latest/user-guide/projects/)
642+
- [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)
643+
- [Kubernetes ValidatingAdmissionPolicy](https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/)
644+
- [https://kubernetes.io/docs/concepts/storage/volumes/#image](https://kubernetes.io/docs/concepts/storage/volumes/#image)
645+
- [https://kubernetes.io/docs/tasks/configure-pod-container/image-volumes/](https://kubernetes.io/docs/tasks/configure-pod-container/image-volumes/)
576646
577647
{{#include ../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)