CVE-2024-27936 (Other, published 2024-03-21T02:52Z)
Description: value: Deno is a JavaScript, TypeScript, and WebAssembly runtime with secure defaults. Starting in version 1.32.1 and prior to version 1.41.0 of the deno library, maliciously crafted permission request can show the spoofed permission prompt by inserting a broken ANSI escape sequence into the request contents. Deno is stripping any ANSI escape sequences from the permission prompt, but permissions given to the program are based on the contents that contain the ANSI escape sequences. Any Deno program can spoof the content of the interactive permission prompt by inserting a broken ANSI code, which allows a malicious Deno program to display the wrong file path or program name to the user. Version 1.41.0 of the deno library contains a patch for the issue.
Severity: nan (CVSS v3 base score: )
Weakness: NVD-CWE-noinfo \u2014 Insufficient Information
There is insufficient information about the issue to classify it; details are unkown or unspecified.
Repository: https://github.com/denoland/deno
Files changed:
Cargo.lock
Cargo.toml
cli/Cargo.toml
cli/tests/integration/run_tests.rs
runtime/Cargo.toml
runtime/permissions/prompter.rs
Commit message: fix(prompt): better output with control chars (#18108)



Vulnerable code:
version = "0.3.4"
checksum = "f166cdfb9db0607e2079b382ba64bc4164344006c733b95c1ecfa782a180a34a"
console_static_text = "=0.3.4"
    eprint!("{}", colors::bold(message));
    if let Some(api_name) = api_name {

Fixed code:
version = "0.7.1"
checksum = "953d2c3cf53213a4eccdbe8f2e0b49b5d0f77e87a2a9060117bbf9346f92b64e"
 "console_static_text",
console_static_text = "=0.7.1"
console_static_text.workspace = true
#[test]
fn permission_prompt_strips_ansi_codes_and_control_chars() {
  let _guard = util::http_server();
  util::with_pty(&["repl"], |mut console| {
    console.write_line(
      r#"Deno.permissions.request({ name: "env", variable: "\rDo you like ice cream? y/n" });"#
    );
    console.write_line("close();");
    let output = console.read_all_output();

    assert!(output.contains(
      "┌ ⚠️  Deno requests env access to \"Do you like ice cream? y/n\"."
    ));
  });

  util::with_pty(&["repl"], |mut console| {
    console.write_line(
      r#"
const boldANSI = "\u001b[1m" // bold
const unboldANSI = "\u001b[22m" // unbold

const prompt = `┌ ⚠️  ${boldANSI}Deno requests run access to "echo"${unboldANSI}
├ Requested by \`Deno.Command().output()`

const moveANSIUp = "\u001b[1A" // moves to the start of the line
const clearANSI = "\u001b[2K" // clears the line
const moveANSIStart = "\u001b[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)"#,
    );
    console.write_line("close();");
    let output = console.read_all_output();

    assert!(output.contains(r#"┌ ⚠️  Deno requests run access to "cat""#));
  });
}

console_static_text.workspace = true
/// Helper function to strip ansi codes and ASCII control characters.
fn strip_ansi_codes_and_ascii_control(s: &str) -> std::borrow::Cow<str> {
  console_static_text::strip_ansi_codes(s)
    .chars()
    .filter(|c| !c.is_ascii_control())
    .collect()
}

    let message = strip_ansi_codes_and_ascii_control(message);
    let name = strip_ansi_codes_and_ascii_control(name);
    let api_name = api_name.map(strip_ansi_codes_and_ascii_control);

    eprint!("{}", colors::bold(message.clone()));
    if let Some(api_name) = api_name.clone() {