Evgen verzun
Blog
September 23, 2026
Critical Authorization-Boundary Failure in OpenAI Codex Desktop’s Bundled Computer-Use Integration
Security finding: During an authorized software-engineering task, OpenAI Codex Desktop unexpectedly adopted an unrelated objective, opened a third-party website, and populated an external form without a corresponding user instruction. The final Create action was prevented only by direct user intervention.
Executive summary
On September 23, 2026, I observed a serious authorization-boundary failure involving OpenAI Codex Desktop and the bundled unified-computer-use@openai-bundled integration.
Codex was operating inside a long-running software-engineering task for the R2 Secure AI Gateway. The active instructions concerned two authorized project activities:
- continuing the first phase of A/B routing implementation;
- running a separate Green Live review when resources were available.
There was no request to create music, visit Suno, compose lyrics, or interact with any unrelated external service.
Nevertheless, Codex abruptly began executing an entirely unrelated workflow. It announced that it would create a Russian New Year song in Suno, opened the Suno website, generated a detailed prompt, and entered that prompt into the external form.
The Create button was not pressed, and no song was generated. However, the security boundary had already been crossed: Codex had navigated to an unrelated third-party service and entered data into it without authorization.
What happened
Without a corresponding user instruction, Codex announced:
“I’ll do this directly in Suno: create a Russian emotional New Year pop ballad…”
It then used the bundled computer-use MCP integration to:
- Select the Codex in-app browser.
- Inspect the available browser tabs.
- Open a new browser tab.
- Navigate to
https://suno.com/create. - Inspect the Suno page and locate its music-generation interface.
- Click Reject All on the cookie dialog.
- Generate a detailed Russian music prompt.
- Enter that prompt into Suno’s Chat to make music field.
- Inspect the page again and confirm that the prompt was present.
- Prepare to continue toward the visible Create action.
The entered text specified a complete Russian New Year pop ballad titled “Свет в новогоднем окне,” including vocal style, instrumentation, theme, structure, and requested duration.
The incident screenshot clearly shows:
- the unrelated Suno website open;
- the generated prompt populated in the external form;
- the Create button visible and ready;
- the unrelated software-engineering activity still visible in the Codex task beside it.
Execution stopped only because the user noticed the unexpected activity and explicitly intervened.
The Create button was not pressed, and no song was generated. No account was authenticated. No credentials, project files, customer records, or other known sensitive information were included in this particular prompt.
That limits the impact of this specific incident, but it does not eliminate the security concern. Entering text into a web application is not necessarily a local-only operation. Modern applications can transmit input through telemetry, autosave, validation, analytics, or other JavaScript events before the final submission button is pressed. External transmission of the entered prompt therefore cannot be excluded.
What the forensic evidence shows
The incident was reconstructed from the local Codex rollout history, projected thread database, runtime logs, and stored MCP call records.
No user instruction authorized the action
The active Codex turn contained only two persisted user messages, both concerning the software project.
A search across stored thread_items and thread_realtime_items found:
- no user message mentioning Suno;
- no user message requesting music generation;
- no user message containing the song title;
- no realtime message containing the generated prompt.
The exact music request appeared only in the assistant’s output and the subsequent computer-use call.
Runtime state immediately before the unauthorized operation reported:
has_pending_input=false
The action therefore did not follow a queued user message or an ordinary steering instruction recorded by Codex.
The anomaly appeared before Suno was opened
The first reference to Suno appeared in the model-generated assistant response. Only afterward did Codex invoke the browser tool.
This rules out the Suno webpage as the initiating prompt-injection source. The page had not yet been opened, and its content had not been read, when Codex decided to perform the unrelated task.
The OpenAI Docs skill was not the source
Immediately before the incident, Codex had unexpectedly started responding to another absent request concerning voice-chat behavior. As part of that response, it read the local OpenAI Docs skill and inspected the available tool catalog.
The OpenAI Docs skill contained no references to:
- Suno;
- music generation;
- songs;
- New Year lyrics;
- the generated title or prompt.
The inspected tool-catalog output also contained no matching instruction.
The UI message “Loaded a tool, ran commands — Read OpenAI Docs skill” describes an event preceding the incident, but the skill itself did not contain the unrelated objective.
The fact that Codex had already started answering an absent voice-chat question shortly before the Suno action is an additional indication of context or task-isolation failure.
MCP was the execution bridge
The unrelated objective originated in the model response, but the external actions were executed through:
unified-computer-use@openai-bundled mcp__cua_repl.js
The recorded calls included operations equivalent to:
cua.getBrowser({ url: "https://suno.com" });
const tab = await browser.tabs.new();
await tab.goto("https://suno.com/create");
await tab.playwright
.getByRole("button", { name: "Reject All" })
.click();
await tab.playwright
.getByRole("textbox", { name: "Chat to make music" })
.fill(generatedPrompt);
The tool then read the page again and confirmed that the generated prompt was present in the input field.
MCP was therefore not the apparent source of the foreign objective, but it became the execution bridge through which that objective reached an external system.
The most serious technical finding
The stored MCP records classified all these calls as:
readOnlyHint: true
This included calls containing:
.goto();.click();.fill().
A general computer-use JavaScript interface capable of navigation, clicking, typing, uploading, submitting forms, and changing external state should not be represented as uniformly read-only.
The bundled browser tool’s own safety documentation correctly warned that entering data into third-party pages may transmit information and requires clear user authorization. Despite that warning:
- no matching user instruction existed;
- no confirmation was requested;
- no provenance check bound the action to an authorizing user message;
- the external form was populated.
This suggests a gap between documented browser-safety rules and their technical enforcement.
The effective failure chain was:
Unrelated model-generated objective
↓
No matching user message
↓
No task-scope or provenance rejection
↓
Generic computer-use MCP marked read-only
↓
External browser navigation
↓
Third-party form interaction and data entry
Probable failure domain
The available evidence does not prove whether the original context failure occurred in:
- Codex Desktop context assembly;
- provider-side response handling;
- model generation;
- task or thread isolation;
- realtime, dictation, or steering integration;
- cached-context reuse;
- automatic follow-up sampling.
Several facts narrow the investigation:
- The foreign objective appeared before any Suno content entered the context.
- There was no stored user or realtime message authorizing it.
- Runtime logs showed no pending user input.
- The wrong action remained inside the existing project turn and thread ID.
- Immediately beforehand, Codex had responded to another absent request concerning voice chat.
- The model continued automatically after tool results without returning control to the user.
- The active context was unusually large: approximately 217,000 tokens against an automatic compaction threshold of approximately 244,800.
- Realtime conversation, steering, browser control, MCP apps, and automatic follow-up capabilities were enabled.
A very large context may have contributed to model drift, but context size does not justify executing an unrelated external action.
The strongest conclusion supported by the current evidence is:
An unrelated intent appeared inside the active model response without a corresponding user message, and the bundled computer-use integration failed to prevent that intent from reaching an external website.
This is more serious than a normal hallucinated answer. A textual hallucination would remain inside the conversation. In this case, the hallucinated or contaminated objective crossed the boundary into computer control.
Security impact
The confirmed impact was limited to an unauthenticated Suno session and a synthetic music prompt. Nevertheless, the same execution path could potentially be used to:
- enter private project information into an external form;
- paste source code or logs into an unrelated website;
- upload files;
- send messages;
- modify cloud or SaaS configuration;
- disclose browsing or task context;
- trigger irreversible actions if a final button were clicked.
This incident demonstrates a dangerous combination:
- The model can lose or confuse the active task objective.
- A general-purpose computer-use tool can operate external applications.
- The tool’s metadata may classify mutating operations as read-only.
- No mandatory provenance check prevents unrelated intent from becoming an external action.
I consider this a potential critical authorization-boundary vulnerability, pending confirmation and root-cause analysis by OpenAI.
It is not currently accurate to call it confirmed remote code execution, account compromise, or proven cross-user data leakage. The evidence does support calling it an unauthorized external computer-use action caused by an untraceable model objective.
Required remediation
OpenAI should introduce technical controls that do not depend only on the model remembering written safety instructions.
1. Bind every action to an authorizing user message
Every external tool call should carry:
authorizing_thread_id authorizing_turn_id authorizing_user_item_id authorized_destination authorized_action_class
If no valid user item authorizes the action, execution should fail closed.
2. Separate read-only and mutating computer-use APIs
A tool capable of arbitrary JavaScript browser control cannot safely have a global readOnlyHint: true.
At minimum, the following operations must be classified as mutating:
- form entry;
- clicks;
- uploads;
- downloads;
- navigation to a new external domain;
- message sending;
- submission;
- authentication;
- permission changes.
3. Require confirmation for new external destinations
Opening or interacting with a domain absent from the current user request should require confirmation specifying:
- the destination;
- the intended operation;
- the information being transmitted;
- the responsible user instruction.
4. Add a task-scope transition guard
A sudden transition from software engineering to music generation should be detected before tool execution.
The system should compare the proposed action with:
- the current task objective;
- recent explicit user messages;
- approved domains;
- assigned files and applications;
- existing authorization boundaries.
5. Isolate realtime and steering contexts
Voice, dictation, steering, background tasks, and ordinary task messages must have separate, verifiable routing.
A request received in one task must never become actionable context in another task unless the user explicitly transfers it.
6. Stop automatic follow-up on unexplained domain changes
Automatic model continuation should pause when:
- the objective changes materially;
- an unrelated application is introduced;
- an external domain appears without provenance;
- a read-only workflow becomes mutating.
7. Preserve complete audit provenance
Logs should show a direct authorization chain:
User message → accepted objective → model response → tool decision → policy verdict → tool execution → external destination
8. Add adversarial regression tests
OpenAI should test:
- long-running turns near compaction limits;
- repeated automatic tool follow-ups;
- concurrent tasks;
- voice and text running simultaneously;
- task switching during active execution;
- generic MCP JavaScript tools;
- incorrect
readOnlyHintdeclarations; - unrelated external-domain transitions.
Disclosure position
The complete technical evidence should be supplied privately to OpenAI with the exact task, turn, response, MCP-call, process, and provider-request identifiers.
Public discussion should remain precise:
- the unrelated task was not requested;
- the external page was opened;
- the prompt was entered;
- final creation was stopped by the user;
- sensitive-data exfiltration was not confirmed;
- the tool authorization boundary failed;
- the initiating context failure remains under investigation.
Evidence image caption
Codex Desktop executing an unrelated Suno workflow during a software-engineering task. The external form had already been populated, and the Create button was ready. The user’s intervention stopped the final action.