Detect Argo CD AppProject Restriction Bypass via PreDelete/PostDelete Resource Hooks (CVE-2026-77459) in CrowdStrike LogScale
Detects exploitation of CVE-2026-77459, an improper authorization flaw (CWE-863) in Argo CD where AppProject destination-namespace and resource-kind restrictions are not enforced for PreDelete and PostDelete resource hooks. A user with permission to manage an Application scoped to a restricted AppProject can embed a hook resource (e.g. a Job, Pod, or RBAC object annotated with argocd.argoproj.io/hook: PreDelete or PostDelete) targeting a namespace or resource kind outside the AppProject allow-list. When the Application or a resource is deleted, the argocd-application-controller applies the hook with its own cluster-wide service account, bypassing the project guardrails and enabling privilege escalation and cross-tenant resource creation. Affected: Argo CD v2.10.0-2.14.21, v3.0.0-3.3.14, v3.4.0-3.4.9, v3.5.0-3.5.3, and v3.6.0-rc1. This detection surfaces hook resources applied to out-of-project namespaces/kinds by the Argo CD application controller service account around Application delete operations.
MITRE ATT&CK
LogScale Detection Query
#event_simpleName=KubernetesAuditEvent
| user.username="system:serviceaccount:argocd:argocd-application-controller"
| verb=/create|patch|apply/
| annotations=/argocd\.argoproj\.io\/hook/
| annotations=/PreDelete|PostDelete/
| objectRef.resource=/jobs|pods|rolebindings|clusterrolebindings|roles|clusterroles|serviceaccounts/
| groupBy([user.username, verb, objectRef.resource, objectRef.namespace], function=count()) CrowdStrike CQL query over Kubernetes audit telemetry flagging Argo CD controller delete-phase hook resource creation against privileged kinds (CVE-2026-77459).
Data Sources
Required Tables
False Positives & Tuning
- In-namespace cleanup hooks
- Maintenance workloads under controller identity
- Rollout controllers emitting hook annotations
Other platforms for CVE-2026-77459
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1 PreDelete hook targeting out-of-project namespace
Expected signal: Kubernetes audit event: create jobs in namespace restricted-target with annotation argocd.argoproj.io/hook=PreDelete by the controller service account
- Test 2 PostDelete hook creating privileged RBAC binding
Expected signal: Kubernetes audit event: create clusterrolebindings with annotation argocd.argoproj.io/hook=PostDelete
- Test 3 Hook pod in kube-system namespace
Expected signal: Kubernetes audit event: create pods in kube-system with argocd.argoproj.io/hook annotation
References (8)
- https://github.com/argoproj/argo-cd/security/advisories/GHSA-fmxq-cgp8-87wp
- https://nvd.nist.gov/vuln/detail/CVE-2026-77459
- https://github.com/advisories/GHSA-fmxq-cgp8-87wp
- https://github.com/argoproj/argo-cd/commit/1149cdc6e932208c4402183cc3d7b7485239940c
- https://github.com/argoproj/argo-cd/releases/tag/v3.3.15
- https://github.com/argoproj/argo-cd/releases/tag/v3.4.10
- https://github.com/argoproj/argo-cd/releases/tag/v3.5.4
- https://github.com/argoproj/argo-cd/releases/tag/v3.6.0-rc2
Response Playbook
Triage
- Confirm the Argo CD server/controller version against the affected ranges (v2.10.0-2.14.21, v3.0.0-3.3.14, v3.4.0-3.4.9, v3.5.0-3.5.3, v3.6.0-rc1); if in range the environment is exploitable.
- Retrieve the alerting audit event and identify the hook resource kind, target namespace, and the owning Application/AppProject. Compare the target namespace and kind against the AppProject's permitted destinations and clusterResourceWhitelist/namespaceResourceWhitelist.
- Determine which user/SSO identity last modified the owning Application manifest or Git source, and whether that user is authorized to target the out-of-project namespace/kind directly.
- Inspect the hook resource body for privileged intent (RBAC bindings to cluster-admin, Jobs running privileged pods, service account token mounts) to gauge impact.
Containment
- Patch Argo CD to a fixed release (3.3.15, 3.4.10, 3.5.4, or 3.6.0-rc2) and restart argocd-application-controller.
- Immediately delete any unauthorized hook-created resources (RBAC bindings, Jobs, Pods) in out-of-project namespaces and revoke any tokens/service accounts they created.
- Temporarily restrict Application/AppProject edit RBAC in Argo CD for untrusted tenants and disable automated delete-phase hooks for multi-tenant projects until patched.
Evidence Collection
- Export the full Kubernetes audit log entries for the controller service account over the exposure window, including requestObject manifests of hook resources.
- Capture the Git commit history and Argo CD Application spec revisions that introduced the PreDelete/PostDelete hook annotations.
- Preserve controller logs (argocd-application-controller) and any created Job/Pod logs and RBAC objects before deletion.
Escalation Criteria
- !Escalate to incident response if hook resources created RBAC bindings granting cluster-admin or cross-tenant access, or if workloads ran in namespaces outside the AppProject allow-list.
- !Escalate if evidence shows the bypass was used to read secrets, create service account tokens, or pivot to other tenants' namespaces.
Investigation Guide
Forensic Artifacts
- >
Kubernetes audit log entries for system:serviceaccount:argocd:argocd-application-controller creating/patching annotated hook resources - >
Argo CD Application spec and Git revision introducing argocd.argoproj.io/hook: PreDelete/PostDelete annotations - >
Created RBAC objects, Jobs, Pods and any service account tokens in out-of-project namespaces
Tuning Guidance
Build an allow-list of (AppProject -> permitted destination namespaces and resource kinds) and suppress events where the hook target matches the AppProject allow-list. Focus alerting on hook resources targeting kube-system, cluster-scoped RBAC, or namespaces not declared in any AppProject destination. After patching to a fixed version, keep the hunt active but lower severity, as the controller should enforce restrictions.
Hunting Queries
Baseline which namespaces and resource kinds receive Argo CD delete-phase hooks; investigate any namespace outside expected AppProject destinations.
KubeAuditLogs | extend d=parse_json(AuditData) | where tostring(d.user.username)=="system:serviceaccount:argocd:argocd-application-controller" | extend ann=tostring(d.requestObject.metadata.annotations), ns=tostring(d.objectRef.namespace) | where ann has "argocd.argoproj.io/hook" and (ann has "PreDelete" or ann has "PostDelete") | summarize count() by ns, tostring(d.objectRef.resource) index=k8s_audit sourcetype="kube:apiserver:audit" user.username="system:serviceaccount:argocd:argocd-application-controller" | spath path=requestObject.metadata.annotations output=ann | search ann="*argocd.argoproj.io/hook*" (ann="*PreDelete*" OR ann="*PostDelete*") | stats count by objectRef.namespace, objectRef.resource Atomic Red Team Tests
Simulates an Application with a PreDelete hook Job annotated to run in a namespace outside the AppProject destination allow-list.
Command
kubectl apply -f - <<'EOF'
apiVersion: batch/v1
kind: Job
metadata:
name: predelete-hook-test
namespace: restricted-target
annotations:
argocd.argoproj.io/hook: PreDelete
spec:
template:
spec:
restartPolicy: Never
containers:
- name: probe
image: busybox:1.36
command: ["sh","-c","echo predelete-hook-fired"]
EOF Cleanup
kubectl delete job predelete-hook-test -n restricted-target --ignore-not-found Expected Telemetry
Kubernetes audit event: create jobs in namespace restricted-target with annotation argocd.argoproj.io/hook=PreDelete by the controller service account
Expected Detection
Detection fires on PreDelete hook Job created in an out-of-project namespace.
Simulates a PostDelete hook that creates a ClusterRoleBinding, representing privilege escalation via the restriction bypass.
Command
kubectl apply -f - <<'EOF'
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: postdelete-hook-crb-test
annotations:
argocd.argoproj.io/hook: PostDelete
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: default
namespace: default
EOF Cleanup
kubectl delete clusterrolebinding postdelete-hook-crb-test --ignore-not-found Expected Telemetry
Kubernetes audit event: create clusterrolebindings with annotation argocd.argoproj.io/hook=PostDelete
Expected Detection
Detection fires on PostDelete hook creating a cluster-scoped RBAC binding.
Simulates a delete-phase hook pod placed in kube-system, a namespace no tenant AppProject should permit.
Command
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: hook-pod-test
namespace: kube-system
annotations:
argocd.argoproj.io/hook: PreDelete
spec:
restartPolicy: Never
containers:
- name: probe
image: busybox:1.36
command: ["sh","-c","sleep 5"]
EOF Cleanup
kubectl delete pod hook-pod-test -n kube-system --ignore-not-found Expected Telemetry
Kubernetes audit event: create pods in kube-system with argocd.argoproj.io/hook annotation
Expected Detection
Detection fires on a delete-phase hook pod in kube-system.