# Argo CD Security {{#include ../banners/hacktricks-training.md}} ## Basic Information [Argo CD](https://argo-cd.readthedocs.io/) 是一个用于 Kubernetes 的 GitOps continuous delivery platform。它监视 Git repositories,使用 Helm、Kustomize、Jsonnet 或 config management plugins 等工具渲染 Kubernetes manifests,并将 live cluster state 与 Git 中存储的 desired state 进行协调。 从攻击者的角度来看,应将 Argo CD 视为一个**拥有 Kubernetes credentials 的 deployment engine**。一次有效的 Argo CD compromise 可能导致: - 访问 private Git repositories 和 repository credentials。 - 访问 Argo CD 使用的 Kubernetes cluster secrets。 - 在 `argocd-repo-server` 中执行 manifest generation code。 - 通过受信任的 Git repositories、Argo CD applications 或 cache manipulation,未经授权地部署 Kubernetes objects。 ## Architecture & Interesting Components 常见的 Kubernetes objects 和 services: ```bash kubectl get pods,svc,endpoints,ingress -A | grep -iE 'argocd|argo-cd' kubectl get applications,appprojects,applicationsets -A 2>/dev/null kubectl get secrets,configmaps -n argocd 2>/dev/null kubectl get networkpolicy -n argocd 2>/dev/null ``` 值得关注的服务: - **`argocd-server`**:公共 API、web UI、CLI API、身份验证和授权。 - **`argocd-application-controller`**:比较期望状态和实际状态,然后将资源应用到 Kubernetes。 - **`argocd-repo-server`**:克隆仓库、缓存 Git 数据,并运行 Helm/Kustomize/Jsonnet/plugins 以生成 manifests。默认 gRPC 端口为 **8081**。 - **`argocd-redis`**:用于缓存 application、manifest 和 Git reference 数据。默认 Redis 端口为 **6379**。 - **`argocd-applicationset-controller`**:根据 Git、SCM、clusters 和 pull requests 等 generators 生成 Argo CD `Application` 对象。 从已被攻陷的 pod 或内部网络 segment 中,检查内部可达性: ```bash nc -vz 443 nc -vz 8081 nc -vz 6379 ``` ## Public API / UI 攻击 如果你拥有 Argo CD credentials 或发现了暴露的实例,请从常规 API surface 开始: ```bash argocd login argocd account get-user-info argocd account list argocd proj list argocd app list argocd repo list argocd cluster list argocd admin settings rbac can ``` 有用的攻击路径: - **Application 写入权限**:修改 `source.repoURL`、`source.path`、Helm values、Kustomize options、plugin settings 或 sync options,使 Argo CD 部署攻击者控制的 manifests。 - **Project 配置错误**:`AppProject` objects 可能允许宽泛的 `sourceRepos`、宽泛的 `destinations`、不安全的 `clusterResourceWhitelist` 或薄弱的 namespace restrictions。 - **Repository credential abuse**:repository secrets、GitHub App credentials、SSH keys 和 tokens 可能允许向受信任的 repos 推送内容或添加恶意 dependencies。 - **Cluster credential abuse**:cluster secrets 可能包含 bearer tokens 或 exec-provider configuration,供 Argo CD 部署到目标 clusters。 - **Local admin / project tokens**:长期有效的 Argo CD tokens 可通过 API 重用,除非已被 revoke 或过期。 当你拥有 cluster read access 时,从 Kubernetes 枚举 configuration: ```bash kubectl get applications.argoproj.io -A -o yaml kubectl get appprojects.argoproj.io -A -o yaml kubectl get applicationsets.argoproj.io -A -o yaml kubectl get secrets -n argocd -o yaml | grep -nE 'repoURL|sshPrivateKey|password|bearerToken|githubApp|tlsClientCertData|tlsClientCertKey' kubectl get cm -n argocd argocd-cm argocd-rbac-cm argocd-cmd-params-cm -o yaml ``` ## Trusted Git Repository Abuse 如果你可以向 Argo CD 信任的 repository push,通常就能影响部署的内容。影响取决于 `AppProject` 的边界,以及 application controller 使用的 service account 权限。 常见的 payload 位置: - application path 下的原始 Kubernetes YAML。 - Helm chart templates 和 `values.yaml`。 - Kustomize overlays、remote bases 和 generators。 - Jsonnet 或 config management plugin 的输入。 - 用于创建或更新 `Application` 对象的 ApplicationSet generator 文件。 检查应用是否使用 automated sync、pruning、self-heal、sync windows 或 manual approvals: ```bash kubectl get applications.argoproj.io -A \ -o custom-columns='NS:.metadata.namespace,APP:.metadata.name,PROJECT:.spec.project,AUTOSYNC:.spec.syncPolicy.automated,REPO:.spec.source.repoURL,PATH:.spec.source.path,DEST:.spec.destination.server' ``` ## 直接滥用 `argocd-repo-server` 不要假设 public Argo CD API 是唯一的攻击面。Argo CD 内部组件通过 gRPC 与 `argocd-repo-server` 通信。如果任意 pod 都能访问 repo-server,攻击者控制的内部请求可能绕过通常由 `argocd-server` 强制执行的检查。 实用检查: ```bash kubectl get svc -n argocd argocd-repo-server -o yaml kubectl get endpoints -n argocd argocd-repo-server -o wide nc -vz 8081 ``` 值得关注的迹象: - repo-server gRPC endpoint 可从非 Argo CD pods 访问。 - 缺少 NetworkPolicies,或仅允许 egress 白名单而未拒绝 ingress。 - repo-server 可访问 custom config management plugins、decryption tools,或来自多个 tenants 的 repository 内容。 - Redis 可从非 Argo CD pods 访问;如果凭据可用或不需要凭据,可能允许进行 cache inspection 或 tampering。 ## 未认证的 Repo-Server RCE via Kustomize Options 2026 年 7 月,Synacktiv 披露了 Argo CD 中的一条未认证 code execution chain:当攻击者能够访问内部 gRPC service 时,可对 `repo-server` 发起攻击。该攻击滥用对 `/repository.RepoServerService/GenerateManifest` 的直接访问,以及由攻击者控制的 `KustomizeOptions`。 其中的危险 primitive 是强制 repo-server clone 由攻击者控制的 repository 内容,并运行带 Helm support 的 Kustomize: ```bash kustomize build --enable-helm --helm-command ./payload.sh ``` 最小恶意 Kustomize 输入需要触发 Helm 处理: ```yaml helmCharts: - name: pwn version: 0.0.1 ``` 为什么这能生效: - `argocd-repo-server` 会在渲染前 clone repository。 - `--helm-command ./payload.sh` 会解析为相对于 cloned repository 的路径。 - 如果 attacker 能够控制 rendered repository 和 Kustomize build options,则无需注入 shell metacharacter 也能实现 code execution。 在 Synacktiv 于 2026 年 7 月 1 日披露时,他们报告称该问题尚无官方修复或 CVE。应首先将其视为 network-exposure issue:利用需要能够访问内部 repo-server gRPC port。 ## Redis Cache Poisoning to Deploy Manifests 在 `argocd-repo-server` 中实现 code execution 后,或使用有效 credentials 直接访问 Redis 后,检查 Redis-backed cache entries。Argo CD 通常会存储 gzip-compressed JSON values。 Interesting key prefixes: ```text mfst|... # cached rendered manifests git-refs|... # Git branch/ref to commit mappings app|... # application resource/cache data cluster|... # cluster cache information ``` Synacktiv 描述的 cache poisoning attack 滥用了两部分状态: 1. 修改相关的 `mfst|...` manifest cache 条目,使其包含攻击者控制的 Kubernetes manifest。 2. 修改相关的 `git-refs|...` 映射,使 Argo CD 认为分支已发生移动,然后重新 reconcile 到缓存的 revision。 影响: - 启用 Auto Sync 时,Argo CD 可能会自动应用被污染的缓存 manifest。 - 未启用 Auto Sync 时,用户手动 sync application 仍可能应用 payload。 - 最终影响受目标 application 的 destination 以及 Argo CD 可用的 Kubernetes 权限限制。 ## ApplicationSet Attacks ApplicationSet 尤其敏感,因为它会根据 generator 输出创建或更新 `Application` 对象。 检查: ```bash kubectl get applicationsets.argoproj.io -A -o yaml kubectl get appprojects.argoproj.io -A -o yaml ``` 有趣的模式: - Git generators 读取 attacker-writable files,而这些文件可控制 app names、paths、projects 或 destinations。 - 面向 public repositories 的 Pull request generators,其中 untrusted contributors 可以影响生成的 applications。 - 允许使用 broad destination clusters/namespaces 的 Template fields。 - 允许 `sourceRepos: ["*"]` 或 broad `destinations` 的 AppProjects。 - 继承 automated sync 和 pruning 的 Generated applications。 ## Post-Exploitation 从 Argo CD pod shell 中,优先检查: ```bash env cat /proc/1/environ 2>/dev/null | tr '\0' '\n' find /var/run/secrets /app/config -type f -maxdepth 4 2>/dev/null mount | grep -E 'secret|token|config' ``` 有用的目标: - 窃取 `REDIS_PASSWORD` 或 Redis TLS/client material。 - 从挂载的 secrets 或 Argo CD Kubernetes secrets 中提取 repository credentials。 - 识别 Argo CD 使用的 cluster credentials。 - 读取生成的 manifests 和 plugin output,其中可能包含注入的 secrets。 - 检查 custom plugins、SOPS、Helm secrets、Vault plugins 或 cloud CLIs 是否暴露 decryption keys 和 cloud credentials。 ## Detection & Hardening 重要检查项: - 使用 NetworkPolicies 限制 `argocd-repo-server` 端口 **8081** 和 Redis 端口 **6379**,确保只有预期的 Argo CD 组件可以访问它们。 - 在 Helm deployments 中,确认确实创建了 network policies。Argo CD Helm chart 的 values 长期以来默认将 component network policy creation 设置为 disabled。 - 保持 `argocd-server` 作为经过认证的入口点。内部服务不应被任意 workloads 访问。 - Disable 未使用的 config management tools 和 plugins。 - 限制 `AppProject` 的 `sourceRepos`、`destinations`、namespace permissions 和 cluster-scoped resources。 - 避免将 broad repository credentials 存储在低权限 Argo CD user 可以促使其复用的位置。 - 监控 repo-server requests、Kustomize build options、plugin executions、Redis writes,以及对 `mfst|` / `git-refs|` keys 的异常访问。 - 在发生 compromise 后,rotate Argo CD local users、project tokens、repository credentials 和 cluster credentials。 有用的命令: ```bash kubectl get networkpolicy -n argocd kubectl get networkpolicy -A | grep -i argocd kubectl describe networkpolicy -n argocd argocd-repo-server-network-policy 2>/dev/null kubectl describe networkpolicy -n argocd argocd-redis-network-policy 2>/dev/null ``` ## CodeQL 中的 Static Analysis Note:Typed API Requests 对于使用 gRPC/REST handlers 的 Go services,当 raw input 被 unmarshaled 到 typed request objects 后,默认的 CodeQL remote sources 可能会遗漏 flows。对于 Argo CD-style services,一个有用的 model 是: - Receiver type,例如 `Server` 或 `Service`。 - First parameter 是 `context.Context`。 - Second parameter 是 typed request object。 将 second parameter model 为 remote source,并为 `exec.Command` / `exec.CommandContext` arguments 添加 custom sinks。这有助于发现从 internal API request fields 流向 command execution helpers 的 flows。 ## References - [Synacktiv - Caught in the Octopus Trap: Unauthenticated RCE in Argo CD with CodeQL](https://www.synacktiv.com/en/publications/caught-in-the-octopus-trap-unauthenticated-rce-in-argo-cd-with-codeql) - [Argo CD docs - Security considerations](https://argo-cd.readthedocs.io/en/stable/operator-manual/security/) - [Argo CD docs - High Availability](https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/) - [Argo CD docs - repo-server command reference](https://argo-cd.readthedocs.io/en/stable/operator-manual/server-commands/argocd-repo-server/) - [Argo CD - repo-server NetworkPolicy manifest](https://github.com/argoproj/argo-cd/blob/master/manifests/base/repo-server/argocd-repo-server-network-policy.yaml) - [Argo CD docs - metrics](https://argo-cd.readthedocs.io/en/latest/operator-manual/metrics/) - [Argo Helm - chart values reference](https://github.com/argoproj/argo-helm/blob/main/charts/argo-cd/README.md) - [Kustomize - Helm chart generator example](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/chart.md) {{#include ../banners/hacktricks-training.md}}