Safeguard
Kubernetes Security

Broken object-level authorization in Kubernetes integrations: CVE-2023-1065

One leaked Integration ID was enough to pollute a Snyk customer's findings — CVE-2023-1065 shows why possession of an identifier is not authorization.

Safeguard Research Team
Research
6 min read

On February 28, 2023, NVD published CVE-2023-1065, a vulnerability in every version of Snyk's kubernetes-monitor agent before 2.0.0. The flaw was simple to describe and easy to miss: an unauthenticated attacker who learned a target organization's Integration ID — the identifier the in-cluster agent uses to post scan results back to Snyk — could submit arbitrary data against that ID with no further credential check. NVD scored it 5.3 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N); Snyk's own CNA scoring came in at 6.5, adding an availability impact NVD didn't credit. NVD's classification is CWE-287, Improper Authentication, but the actual failure mode is one the industry usually calls BOLA, or broken object-level authorization: the API treated knowledge of an object identifier as proof of the right to write to that object. Fixed in 2.0.0 via pull request #1275, the bug never exposed customer data — its real-world consequence was quieter and arguably more corrosive: a way to bury genuine security findings under attacker-submitted noise. This post uses it as a case study for the broader pattern and how to test Kubernetes-integrated tools for it.

What actually went wrong in CVE-2023-1065?

The kubernetes-monitor agent runs inside a customer's cluster and periodically posts workload and vulnerability data back to Snyk's backend, tagged with the customer's Integration ID so the platform knows which organization the data belongs to. The vulnerable endpoint accepted that ID as the sole basis for accepting a write — it didn't verify the request originated from the agent instance that was actually provisioned with that ID, or from any authenticated principal tied to the organization. Snyk's own advisory (published at snyk.io/blog/api-auth-vuln-snyk-kubernetes-cve-2023-1065) frames it as an authentication gap on an internal API; functionally, it's the identifier-as-credential mistake that defines BOLA. Anyone who obtained an Integration ID — through log exposure, a misconfigured CI variable, or simple guessing if IDs weren't sufficiently random — could post irrelevant or misleading data into that customer's findings stream, degrading trust in the platform's output without ever touching the customer's actual source code or cluster.

Why does NVD call this "Improper Authentication" instead of BOLA?

CWE labeling for this exact failure pattern is inconsistent across the industry, and CVE-2023-1065 is a clean example of why you shouldn't triage by CWE tag alone. NVD assigned CWE-287, Improper Authentication — reasonable, since the endpoint never authenticated the caller at all. But OWASP's API Security Top 10 treats this pattern under API1:2023, Broken Object Level Authorization, because the observable symptom is that object ownership was never checked before granting write access to that object. There's no single CWE that both trackers converge on for "identifier used as an implicit bearer token": some CVEs in this family get tagged CWE-639 (Authorization Bypass Through User-Controlled Key), others CWE-284 (Improper Access Control), others CWE-287 like this one. The practical lesson: define BOLA by its mechanism — an object reference that grants access without a corresponding ownership or authentication check — not by searching your CVE database for a specific CWE number, or you'll miss instances filed under a different tag.

Why is this pattern especially dangerous in Kubernetes-integrated tools specifically?

Kubernetes-integrated security and observability agents are structurally exposed to this pattern because they're built around a many-cluster-to-one-backend architecture where an identifier — an Integration ID, cluster ID, or agent token — is the only thing distinguishing one customer's data stream from another's at scale. A SaaS platform monitoring thousands of customer clusters needs a cheap way to route inbound telemetry to the right tenant, and an object identifier embedded in the agent's configuration is the obvious mechanism. That's efficient, but it collapses routing and authorization into the same field unless the backend separately verifies that the caller is entitled to write under that ID — for example, by binding the ID to a signed, per-agent credential issued at install time rather than trusting the ID as self-authenticating. Snyk's fix in 2.0.0 addressed exactly that gap. Any tool that deploys an in-cluster agent reporting back to a multi-tenant control plane — scanners, policy engines, cost tools, log shippers — has the same architectural shape and the same class of risk to rule out.

What does NVD mean by "does not expose user data or create direct security risks"?

NVD's characterization matters because it draws a line between a confidentiality breach and an integrity attack, and CVE-2023-1065 sits squarely on the integrity side. The vulnerability didn't let an attacker read another organization's vulnerabilities, source code, or cluster contents — the vector had no confidentiality impact (C:N in both scoring vectors). What it enabled was pollution: submitting bogus findings into a legitimate customer's data stream. That's a lower-severity bug by CVSS math, but it has an operational cost that a pure information-disclosure bug doesn't — a security team that starts seeing implausible or contradictory findings from their scanning tool has to spend time distinguishing signal from injected noise, and in the worst case, learns to distrust or ignore the tool's alerts altogether. Availability and integrity impacts that degrade trust in a security control are a distinct risk category from data exposure, and they deserve their own place in a threat model even when the CVSS score looks unremarkable next to a critical RCE.

How do you test your own Kubernetes-integrated tools for this exact pattern?

Testing for BOLA in an agent-to-backend architecture means treating every identifier the agent sends as a potential authorization bypass, not just a routing key. Start by enumerating every endpoint your in-cluster or in-CI agents call and asking, for each one: what does the backend check besides the object ID itself? If the answer is "nothing" — no signed agent credential, no mTLS client cert, no session token bound to that ID at provisioning time — you have the shape of CVE-2023-1065. Concretely: capture an agent's outbound request, strip or swap the credential while keeping the object ID, and replay it from a different network context; if the write still succeeds, the ID is functioning as a bearer token. Also check whether IDs are guessable or sequential (sequential integers are a gift to this bug class; UUIDs raise the bar but don't substitute for an authentication check) and whether they ever leak into logs, CI output, or client-side configuration where they're easy to harvest. When evaluating any vendor's Kubernetes-integrated tooling — including your own — confirm explicitly that possession of an integration or cluster identifier is never sufficient on its own to write data against that tenant; ownership must be proven by a credential the backend independently validates, not implied by knowing the ID.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.