# Argo CD CVE-2026-43824: Read-Only App Access Could Expose Kubernetes Secrets

> Canonical: https://juliet.sh/blog/we-tested-argocd-cve-2026-43824-serversidediff-secret-exposure
> Published: 2026-05-02
> Author: Juliet Security Team
> Tags: kubernetes-security, argocd, gitops, secrets, cve-2026-43824, rbac
> Read time: 8 min read

_We reproduced CVE-2026-43824 in isolated Argo CD 3.2 and 3.3 labs. A read-only Argo CD account with applications get could use ServerSideDiff to receive cleartext managed Secret data when IncludeMutationWebhook=true. Fixed releases 3.2.11 and 3.3.9 masked the same path._

---

CVE-2026-43824 is a new Argo CD vulnerability in `ServerSideDiff`. The official CVE record describes it plainly: Argo CD `3.2.0` before `3.2.11` and `3.3.0` before `3.3.9` allowed cleartext Kubernetes Secret data to be read through the ServerSideDiff path.

The Kubernetes operator question is narrower than "is Argo CD vulnerable?"

If a user has read-only Argo CD application access, can that user get cleartext Secret data for resources managed by that Application?

We tested that in isolated kind labs for both affected release lines:

- Argo CD `v3.2.10`, then upgraded to fixed `v3.2.11`

- Argo CD `v3.3.8`, then upgraded to fixed `v3.3.9`

The short answer: yes, in the affected versions we tested, a read-only Argo CD account with `applications get` could use the ServerSideDiff path to receive cleartext Secret values when the Application used `argocd.argoproj.io/compare-options: IncludeMutationWebhook=true`.

The normal managed-resource view did not show cleartext Secret values in our lab. The vulnerable ServerSideDiff response did.

After upgrading the same labs to `3.2.11` and `3.3.9`, the same path returned masked Secret data.

We are not publishing exploit code or request-shaping details. This writeup is focused on what we validated, which operator conditions matter, and what to inventory.

## Key findings

- A read-only Argo CD account with `applications get` was enough to reach the ServerSideDiff path in our lab.

- The account could read the Application and managed resources, but could not sync the Application.

- With affected Argo CD versions and `IncludeMutationWebhook=true`, ServerSideDiff returned cleartext Secret data in `target_state`.

- Without `IncludeMutationWebhook=true`, our lab did not reproduce cleartext exposure.

- After upgrading to `3.2.11` or `3.3.9`, the same test path returned masked Secret data.

- We reproduced exposure for both a default Argo-created managed Secret and a Secret whose data had a secondary field manager.

- Kubernetes RBAC to `secrets get` was not the gating question. Argo CD application RBAC was.

## What CVE-2026-43824 is

Argo CD supports Server-Side Diff. The Argo CD documentation describes it as a diff strategy that runs a Kubernetes Server-Side Apply dry-run for each Application resource and compares the returned object to live state.

That is useful because admission controllers can participate in diff calculation before sync. It is also sensitive, because the Kubernetes API server's dry-run response can contain fields that should not be returned to an Argo CD user in cleartext.

The GitHub advisory describes the bug as a missing authorization and data-masking gap in the ServerSideDiff endpoint. Other Argo CD endpoints mask Secret data before returning resource state. The vulnerable path constructed diff responses from raw `PredictedLive` and `NormalizedLive` states without applying the same masking.

The relevant affected and fixed versions are:

- Argo CD 3.2: `3.2.0` through `3.2.10` are affected; `3.2.11` is fixed.

- Argo CD 3.3: `3.3.0` through `3.3.8` are affected; `3.3.9` is fixed.

Severity labels differ by source. The GitHub advisory is Critical with CVSS 9.6. The CVE record is High with CVSS 7.7. For operators, the practical question is simpler: do you have affected Argo CD versions, Applications using this diff behavior, managed Secrets, and Argo CD users or tokens with application read access?

## Why this matters in Kubernetes

Kubernetes Secret access is often reviewed through Kubernetes RBAC:

- Who can `get secrets`?

- Which ServiceAccounts can mount which Secrets?

- Which workloads can read Secret-backed environment variables or volumes?

That is still important, but it is not the whole picture for GitOps systems.

Argo CD is a Kubernetes control plane with its own API, users, tokens, projects, and RBAC policy. An Argo CD account that cannot sync an Application, and may not have direct Kubernetes API access to read Secrets, can still be allowed to read Application state.

This bug lived in that control-plane boundary.

The exposure path we validated looked like this:

    Actor
    **Read-only Argo CD account**
    Has `applications get`, but cannot sync the Application.

    Control plane
    **Argo CD Application**
    The account can read Application state through Argo CD.

    Diff path
    **ServerSideDiff on a managed Secret**
    Argo CD asks the Kubernetes API server for a server-side apply dry-run.

    Affected versions
    **Unmasked Secret state returned**
    The vulnerable response exposed cleartext Secret data in our lab.

That is the main lesson: "read-only in Argo CD" can still be a sensitive permission when Application state includes managed Secrets.

## Lab setup

We built two isolated kind clusters and installed Argo CD into each:

- `argocd-cve43824`: Argo CD `v3.3.8`, then upgraded to `v3.3.9`

- `argocd-cve43824-32`: Argo CD `v3.2.10`, then upgraded to `v3.2.11`

Each lab used the same shape:

- In-cluster Git daemon serving a repo with one Kubernetes `Secret`

- Argo CD `Application` named `secret-app`

- Local Argo CD account named `ro`

- Argo CD RBAC granting that account `applications get`

- No Argo CD RBAC granting that account `applications sync`

- A probe that called the ServerSideDiff path with the read-only token and recorded whether Secret fields were masked or cleartext

We verified the `ro` account could read the Application and managed resources. We also verified it could not sync the Application:

`permission denied: applications, sync, default/secret-app
`
That matters because the lab was not "admin token can read everything." It was an Application read path.

## Results

For Argo CD `3.2.10`:

- Without the annotation, we did not observe cleartext exposure, even with a secondary field manager present.

- With `IncludeMutationWebhook=true`, a default Argo-created managed Secret returned cleartext in `target_state`.

- With `IncludeMutationWebhook=true`, a Secret with a secondary field manager also returned cleartext in `target_state`.

For Argo CD `3.2.11`:

- With `IncludeMutationWebhook=true` and a secondary field manager present, the same path returned masked Secret data.

For Argo CD `3.3.8`:

- Without the annotation, we did not observe cleartext exposure, even with a secondary field manager present.

- With `IncludeMutationWebhook=true`, a default Argo-created managed Secret returned cleartext in `target_state`.

- With `IncludeMutationWebhook=true`, a Secret with a secondary field manager also returned cleartext in `target_state`.

For Argo CD `3.3.9`:

- With `IncludeMutationWebhook=true` and a secondary field manager present, the same path returned masked Secret data.

The fixed versions behaved the way operators want: the same read-only access and same Application annotation did not return cleartext Secret values.

## The important nuance

The GitHub advisory explains one extraction condition in terms of Secret data surviving the server-side dry-run response, for example when another field manager owns the data.

That is a useful warning, but it should not become your only inventory condition.

In our purpose-built lab, a default Argo-created managed Secret also returned cleartext through our ServerSideDiff probe under `IncludeMutationWebhook=true`. Its managed fields showed `argocd-controller` owning `.data` through `operation: Update`, not an intentional second Server-Side Apply manager.

Because that differs from the narrowest reading of the advisory's field-manager discussion, we are not turning it into a universal exploitability claim. We are using it as an inventory warning.

So the safer operator framing is:

Do not treat "no second field manager" as proof of safety. Start with affected Argo CD versions, Applications using `IncludeMutationWebhook=true`, managed Secrets, and Argo CD principals with `applications get`.

The second-manager case is still relevant. It just should not be the only thing you check.

## What to check now

### 1. Check the Argo CD server version

Start with the running image:

`kubectl -n argocd get deploy argocd-server \
  -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
`
If you run multiple Argo CD instances, check each namespace and each cluster.

Prioritize any instance running:

- `v3.2.0` through `v3.2.10`

- `v3.3.0` through `v3.3.8`

Upgrade targets are `v3.2.11` or `v3.3.9`.

### 2. Find Applications using `IncludeMutationWebhook=true`

The annotation can contain multiple comma-separated compare options, so search the string rather than checking for exact equality:

`kubectl get applications.argoproj.io -A -o json \
  | jq -r '.items[]
    | select((.metadata.annotations["argocd.argoproj.io/compare-options"] // "")
      | contains("IncludeMutationWebhook=true"))
    | [.metadata.namespace, .metadata.name, .spec.project] | @tsv'
`
Argo CD's documentation describes `IncludeMutationWebhook=true` as a Server-Side Diff option. For normal Argo-generated diffs, that depends on Server-Side Diff being used. For this CVE, however, the vulnerable API path is the ServerSideDiff endpoint itself. In our lab, we directly tested that endpoint with a read-only Argo CD token. Do not treat "we did not globally enable Server-Side Diff" as proof of safety by itself.

It is still useful to check controller-level configuration so you know where Server-Side Diff is intentionally used:

`kubectl -n argocd get configmap argocd-cmd-params-cm \
  -o jsonpath='{.data.controller\.diff\.server\.side}{"\n"}'
`
### 3. Identify managed Secrets in those Applications

For each high-priority Application, identify whether it manages Kubernetes `Secret` resources. You can use Argo CD's normal managed-resource view, the CLI, or your inventory system.

The operator question is:

`affected Argo CD instance
    + Application has IncludeMutationWebhook=true
    + Application manages one or more Secrets
    + user/group/token has applications get
`
That is the exposure path to review.

Juliet users can inventory this as an exposure path by looking for affected Argo CD versions, Applications using `IncludeMutationWebhook=true`, managed Secrets, and principals with `applications get`.

### 4. Review Argo CD RBAC for `applications get`

Check the Argo CD RBAC ConfigMap:

`kubectl -n argocd get configmap argocd-rbac-cm -o yaml
`
Look for users, groups, default roles, automation tokens, and project-scoped roles that grant Application read access. Be careful with default roles and broad groups. "Read-only" is not harmless if read access reaches sensitive Application state.

## Mitigations

### Upgrade Argo CD

The primary fix is to upgrade to `3.2.11`, `3.3.9`, or a later patched release.

That is the cleanest mitigation because the fixed versions mask Secret data in the affected ServerSideDiff response path.

### Remove `IncludeMutationWebhook=true` where it is not required

If you cannot upgrade immediately, remove `IncludeMutationWebhook=true` from Applications that do not need mutation webhook output in diff calculations.

This is a compensating control, not a replacement for upgrading. In our lab, removing that condition stopped the cleartext result, but the vulnerability is in Argo CD and should be patched.

### Reduce broad Argo CD application read access

Review who can read Applications in affected instances. Include human users, SSO groups, local accounts, CI tokens, project roles, and any service that stores an Argo CD token.

If a principal does not need broad `applications get`, narrow it.

### Consider Secret rotation if exposure was plausible

If an affected instance had `IncludeMutationWebhook=true`, managed Secrets, and untrusted or broad read-only Argo CD access, treat affected Secret values as potentially exposed.

Whether to rotate depends on your access logs, token population, Application scope, and incident response policy. But do not dismiss the issue because the user was "only read-only" in Argo CD.

## What not to overclaim

This bug is serious without exaggerating it.

Do not claim every Argo CD user can read every Kubernetes Secret. The exposure depends on Argo CD version, Application access, Application resources, and diff behavior.

Do not claim Kubernetes RBAC is irrelevant. Kubernetes RBAC still controls many direct paths to Secrets. The point is that Argo CD introduces an additional control-plane path.

Do not claim every Application leaks. Our lab result depended on `IncludeMutationWebhook=true`.

Do not rely only on second field manager detection. We reproduced cleartext exposure with a default Argo-created managed Secret under the vulnerable annotation.

## FAQ

### Is this a Kubernetes vulnerability?

No. CVE-2026-43824 is an Argo CD vulnerability. Kubernetes matters because Argo CD manages Kubernetes resources, stores Application state, and uses Kubernetes Server-Side Apply dry-run during Server-Side Diff.

### Does a user need Kubernetes `get secrets` permission?

Not for the path we tested. The account in our lab used Argo CD `applications get` access. The issue is that affected Argo CD versions returned unmasked Secret state through ServerSideDiff.

### Does `applications get` really matter?

Yes. In our lab, `applications get` was enough to read the Application and reach the ServerSideDiff path. The same account could not sync the Application.

### Is `IncludeMutationWebhook=true` required?

It was required in our lab. We did not reproduce cleartext exposure without it. The official Argo CD documentation says this annotation includes mutation webhook changes in Server-Side Diff and is only effective when Server-Side Diff is enabled.

### Are fixed versions enough?

In our lab, yes. After upgrading to `3.2.11` and `3.3.9`, the same read-only path and same Application condition returned masked Secret data.

### Should I rotate Secrets?

If affected versions, the vulnerable annotation, managed Secrets, and broad or untrusted Argo CD read access overlapped, rotation is worth considering. Start with the most sensitive Applications and tokens.

## Sources

- [GitHub advisory GHSA-3v3m-wc6v-x4x3](https://github.com/argoproj/argo-cd/security/advisories/GHSA-3v3m-wc6v-x4x3)

- [CVE-2026-43824 record](https://cveawg.mitre.org/api/cve/CVE-2026-43824)

- [Argo CD Server-Side Diff documentation](https://argo-cd.readthedocs.io/en/stable/user-guide/diff-strategies/)

- [Argo CD v3.3.9 release](https://github.com/argoproj/argo-cd/releases/tag/v3.3.9)

- [Argo CD v3.2.11 release](https://github.com/argoproj/argo-cd/releases/tag/v3.2.11)

- [Argo CD v3.3.8 to v3.3.9 compare](https://github.com/argoproj/argo-cd/compare/v3.3.8...v3.3.9)

- [Argo CD v3.2.10 to v3.2.11 compare](https://github.com/argoproj/argo-cd/compare/v3.2.10...v3.2.11)