CVE-2026-81867: Testing JavaScript Task Deserialization and Proving Code Execution
CVE-2026-81867 let a standard-permission author run code on shared Google Cloud servers. Test it with two accounts and prove impact from execution logs.

CVE-2026-81867: Testing JavaScript Task Deserialization and Proving Code Execution
TL;DR
CVE-2026-81867 is a deserialization flaw in the JavaScript Task of Google Cloud Application Integration, rated Critical and patched on June 28, 2026. A standard-permission integration author could cause code to run on shared production servers under the runtime's service identity. The vendor fix covers Google's runtime; it does not prove that no equivalent pattern exists in code you own or answer whether the pre-patch window was abused. Test the primitive with two accounts: a standard author and a privileged identity, same task definition. The finding is a differential response plus an execution log naming the effective principal—not a scanner severity.
What this is
Deserialization of untrusted data (CWE-502) is the bug class where an application rebuilds an object from a byte stream the caller controls, and the stream gets to choose the type. Without a type allowlist, the attacker picks which class is instantiated, and that class's constructors and lifecycle hooks do the rest.
In a JavaScript Task the payload is not a Java gadget chain. It is the runtime's object-revival path: the point where a caller-supplied structure becomes a live object carrying a prototype and, if the boundary is thin, host bindings—file, network, process, or credential access handed to the script by the worker. The bulletin's phrase shared production servers is the risk multiplier. Execution does not land in a sandbox scoped to your project; it lands in a multi-tenant runtime that also serves other customers.
Why it matters
Three populations are in scope, and they fail differently.
- Anyone who ran JavaScript Tasks before June 28, 2026. The patch closes the future. It does not tell you whether a task executed something it should not have during the exposure window.
- Anyone who grants integration authoring broadly. The role reads as builds flows. If authoring reaches execution as the runtime identity, the role is closer to code execution and should be scoped, reviewed, and logged accordingly.
- Anyone who wrote the same pattern themselves. Payload mapping, connector glue, queue consumers, functions that revive objects straight from a request body. The platform fix covers the platform.
If you ignore it, your role model says a standard-permission user cannot execute code, and your logs agree because they record the deputy. Both are wrong in the same direction, and neither raises an alert.
How it works
Affected versions. Google's GCP-2026-065 states that the JavaScript Task in Application Integration was affected before the June 28, 2026 patch (bulletin index). Google patched the managed service on June 28, 2026 and published the bulletin on September 28, 2026. The bulletin gives a vendor severity of Critical; it does not publish a CVSS vector in the excerpt, so take the boundary from the bulletin and check NVD for enrichment rather than guessing a score.
Mechanism. The task takes caller-supplied input, hands it to the runtime's deserialization path, and revives it into an object the script then operates on. When the revived type carries host bindings, the script's subsequent calls execute in the worker's context. The caller's IAM policy is consulted when the task is invoked; it is not consulted for each action the revived object performs. The caller authorizes the call, the runtime authorizes the effect. Structurally this is the confused-deputy family (CWE-441) with a sharper primitive.
The testable hypothesis. You cannot probe Google's patched runtime, and you should not try. The hypothesis you can test in your own environment:
A principal holding only standard integration-author permissions can cause code to run under an identity that outranks it, and can reach data that principal cannot read directly.
Two accounts, one request shape. Account A is a standard-permission integration author. Account B is a privileged identity in a second project or tenant—an owner, or the service identity that owns the data you want to reach. Submit the same task definition as both. Compare three things: whether execution succeeds, which principal the execution log attributes the work to, and whether the response contains a value A cannot fetch through any API A is authorized to call. If A's execution is attributed to the runtime service agent and returns B's value, the boundary is gone and you have the finding.
Detection and response

The telemetry you need is often off by default or short-lived, so confirm availability before you write the query.
- Data Access audit logs for the integration service. Admin Activity logs record configuration changes; execution is data access. Confirm Data Access logging is enabled and check retention before assuming the pre-patch window is still queryable.
- The effective-principal gap. Every execution has two identities: the principal that invoked it and the service agent that ran it. Baseline the pairs you see in normal operation. A new pair—a standard-permission author whose executions suddenly attribute to a service agent in another project—is the highest-signal alert for this bug class.
- Egress from the integration runtime. Code execution outside the intended script means network calls the task definition does not contain. Alert on destinations absent from the task's declared connectors.
- Task version churn. A version created and executed within minutes by an author who has never published before, followed by no further edits.
- Keep the query after the patch. If nothing anomalous appears, you have a clean window and a baseline. Write both down in the ticket.
What to do
- Establish the window. Query audit logs for JavaScript Task executions between your earliest task deployment and June 28, 2026. Record which projects ran them, which principals authored them, and which service agents executed them. If Data Access logging was off, state that in the finding—missing telemetry is a documented gap, not a clean result.
- Review who can author. List every principal bound to integration authoring roles. For each, ask what the role name hides: what can this person cause to execute? Narrow the set, then re-list.
- Find your own copy of the pattern. Locate every place a request body, queue message, or connector payload is revived into an object:
eval,Function,JSON.parsefollowed by prototype-trusting logic, or a serialization library without a type allowlist. Run the two-account test against the one handling the most sensitive data. - Prove the primitive with your own marker. Use a payload whose class you control and whose effect you can observe—a log line, a callback to a host you own, a file in a directory you can read. Do not probe provider-internal paths or other tenants. The deliverable is a reproducible primitive under your own authorization.
- Attach evidence to the finding. Two transcripts (A and B), the execution log line naming the effective principal, and the value A obtained that A's own credentials cannot fetch. A second researcher should be able to replay it.
- Retest after remediation. Changing the role binding or adding a type allowlist is a hypothesis, not a fix. Re-run the same two-account test and attach the new transcript to the closed finding.
FAQ
Is CVE-2026-81867 exploitable without credentials?
No. The bulletin describes an authenticated user with standard permissions. The severity comes from what that authenticated user reaches once the deserialization path is available, not from pre-auth access.
Do I need to patch anything?
The managed service was patched on June 28, 2026, and Google states no customer action is required. That is the vendor's statement about the vendor's code. Your remaining actions are to verify no equivalent pattern exists in code you own, and to hunt the window if you used the JavaScript Task before the patch.
How is this different from CVE-2026-81375?
Different component, different primitive, different evidence. CVE-2026-81375 is a confused-deputy file read through the Email Task's attachment path; the proof is a file the caller should not have been able to read. CVE-2026-81867 is deserialization leading to code execution in the JavaScript Task; the proof is an execution attributed to an identity that outranks the author.
How do I test a deserialization flaw when there is no public PoC?
You do not need one. You need a serialized object whose class you control and whose effect you can observe, plus a second principal to compare against. Reproducibility under your own authorization is the deliverable; a PoC that only works against a patched build proves nothing about your environment.
What makes this a finding instead of a scanner hit?
Two things: a differential response between two accounts, and a log line that names the identity that actually performed the work. A version banner or a CVE match is a lead. The transcript is the finding.
Sources
- Google Cloud security bulletin GCP-2026-065: https://docs.cloud.google.com/support/bulletins/index#gcp-2026-065
- NVD entry for CVE-2026-81867 (check for enrichment): https://nvd.nist.gov/vuln/detail/CVE-2026-81867
- MITRE CWE-502, Deserialization of Untrusted Data: https://cwe.mitre.org/data/definitions/502.html
- MITRE CWE-441, Confused Deputy: https://cwe.mitre.org/data/definitions/441.html
- OWASP Deserialization Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html