Research

Manus: the warning arrived after the email's code ran

Recent research from Salt Labs records Manus executing obfuscated email content as a decoding task before requesting approval, giving researchers access to a user sandbox containing connector credentials. The report says the issue is resolved. The failure explains why approval must precede the first execution.

Warm-paper conceptual illustration of an email entering an active cloud computer, with an approval notice placed after execution has already started.
In this article

Asking an AI to check the latest email sounds like a reading task. In Salt Labs' controlled study of Manus, content from that email reached a Node.js runtime. A security warning then appeared, asking the user to approve a dangerous operation. The code had already run.

The Salt Labs report says the issue has been resolved. The failure leaves a question worth following: how did a request to read an email turn its contents into a program that needed to run?

1 An email borrows the user's operating permissions

Manus can connect to Gmail and find or process messages at a user's request. In this setup, the user has authorized their mailbox, while the researcher can send messages to it. Once the agent encounters the message during its ordinary task, the body can enter its working context. Sending an email grants neither the user's identity nor permission to issue new instructions on the user's behalf.

A natural-language interface can blur that relationship. The user asks to view a message, and its body says another action is required to make the message readable. If the agent accepts that action as a necessary part of the user's task, an outside sender's message gains use of tools authorized by the user.

Manus' sandbox documentation describes an isolated cloud environment for each task, with a filesystem, browser, networking and software tools. It also stores configuration and tokens needed to complete the task. Running programs is an intended capability. Email content promoted into a program can encounter capabilities already available in that task environment.

Sandbox isolation primarily constrains which systems a program may affect. Inside the task remains a separate question: which content is authorized to start a program? The code in the report ran inside the email recipient's task sandbox. The published study describes no virtual-machine escape. For a task connected to a mailbox, remaining inside that environment can still expose valuable data and credentials.

2 Running content in order to read it

The researchers first tried direct command instructions, which required explicit approval. In some Base64 tests, the agent decoded the content with command-line tools or Python but continued to treat the result as untrusted, blocking subsequent execution. JSFuck worked differently. It expresses JavaScript using only the six characters []()!+. The email presented it as a message requiring decoding, and the agent used Node.js to process it.

JSFuck is itself a JavaScript expression. Its project documentation shows how expressions build strings from arrays, booleans and type conversions, then access and invoke functions. For example, ![] + [] produces the string "false". Extracting characters from such strings can construct property names. Further composition can construct and execute functions. A screen full of brackets conceals ordinary words, but the JavaScript engine still executes those characters as code.

A Base64 byte decoder can return text without executing it. Evaluating JSFuck with a JavaScript engine may invoke functions while producing the supposed decoded message. Whether the decoder is a read-only transformation or an interpreter with side effects changes the security result. Calling an action “view content” leaves its actual runtime capabilities unchanged.

Node.js documents --eval as executing the supplied script. What that runtime can access depends on its launch configuration, process privileges and exposed capabilities. Salt Labs records initial JavaScript evaluation, followed by system-command execution and a connection back to researcher-controlled infrastructure through the same route. A program from an outside email could now run in the user's task environment and communicate externally over its network.

3 A refusal after execution cannot stop the first action

The agent eventually recognized the dangerous content. Salt Labs records Node.js processing the message, the payload executing and an approval warning appearing afterwards. The direct-command tests stopped the dangerous action before execution. The JSFuck path completed its first execution before the warning appeared.

An email triggers program execution before an approval warning. The comparison path requests approval before launching the program, so refusal occurs before any execution.
Figure 1. Approval protects the actions that follow it. Preparation, decoding and preview can also execute programs. View full size.

A local model that changes only an in-memory array makes the ordering visible. This code records an execution side effect before adding an approval notice. The array contains "code ran" followed by "approval requested". The notice cannot undo the first entry.

const events = [];
const source = 'events.push("code ran")';
Function('events', source)(events);
events.push('approval requested');
console.log(events);

Moving approval first and declining to invoke Function after refusal leaves only "approval requested" in the array. SOSEC ran this in-memory ordering model to illustrate approval placement. It reproduces neither Manus' model decisions nor its product repair. Product acceptance still needs to follow the real email-to-tool path and observe where the first side effect occurs.

Preview and decoding therefore belong within execution authorization. If a tool may run programs embedded in unfamiliar content, approval must precede its launch. That approval should also correspond to the content, tool and accessible resources about to be used. Permission for an ordinary decoding task should not carry over to a substituted program. Parsing a message into a static structure and presenting its text can instead use an environment with fewer capabilities.

4 Code inside the sandbox can still reach a mailbox

The task sandbox has to call Gmail for the user, making connector credentials important to the impact. Salt Labs reports finding a Gmail OAuth token in its test environment and credentials for other connected services reachable through environment variables. Consequences for Google Drive or GitHub depend on whether the user connected them and which permissions were granted.

An OAuth token represents access granted to an application. The Bearer Token definition explains that possession of a valid token allows its holder to exercise the represented access without proving knowledge of the user's password. Acquiring such a token from the task environment can let an attacker use the service outside the agent's interface. Expiry, scope and server-side restrictions still constrain that access.

Gmail's scope table separates reading, sending and modifying mail. gmail.readonly permits viewing messages and settings, while gmail.send permits sending on the user's behalf. Broader scopes allow additional operations. The published research does not enumerate every test account's complete grants, so reading mail, sending it and using account-recovery messages require separate impact judgments.

Removing an unexpected process from a sandbox cannot ensure that a copied token has become invalid. Suspected connector-credential exposure calls for revoking the corresponding grant at the service provider before reconnecting what is needed. Manus' help documentation says removing a connector clears stored login information, while Google Account settings can revoke third-party access. Whether a password change alone is sufficient depends on how the service treats existing grants.

5 Separate the first execution from the reading task

Salt Labs says the issue was resolved when it published the research. It supplies no Manus patch diff, complete affected-version range or implementation of each protection. Checking whether a repair covers this class of failure requires observing whether email content can still start a program before approval and which credentials that program can reach.

For teams building agents, a useful check is whether ordinary reading and program execution follow different authorization paths. Retrieve the mail body and have a parser return data. If running an untrusted program is genuinely required, its environment should not inherit mailbox tokens, cloud-storage credentials or unrelated files. Network access should cover only the task's necessary destinations. Even when content influences the model's choice, tools and the runtime can still bound the available permissions.

A different JavaScript context alone supplies no such isolation. Node.js' node:vm documentation explicitly warns that it is not a security mechanism for untrusted code. Virtualization, process restrictions and credential isolation constrain different capabilities and need actual authorization tests. Place a fake token in the test environment and observe whether the restricted program can read it, then check access to designated files and restricted network destinations. These results show whether the permission limits work, beyond the agent displaying a final warning.

A user connects a mailbox to reduce the work of handling email. That grant lets the agent read messages for the user. Its permission to execute programs must follow the user's task and stay unchanged by instructions an outside sender places in a message.