summaryrefslogtreecommitdiff
path: root/cli/args
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2024-09-04 14:51:24 +0200
committerGitHub <noreply@github.com>2024-09-04 14:51:24 +0200
commit74fc66da110ec20d12751e7a0922cea300314399 (patch)
treeb0b057b7539b506b8db39287cd799e7c9cbd526f /cli/args
parent334c842392e2587b8ca1d7cc7cc7d9231fc15286 (diff)
fix: lock down allow-run permissions more (#25370)
`--allow-run` even with an allow list has essentially been `--allow-all`... this locks it down more. 1. Resolves allow list for `--allow-run=` on startup to an absolute path, then uses these paths when evaluating if a command can execute. Also, adds these paths to `--deny-write` 1. Resolves the environment (cwd and env vars) before evaluating permissions and before executing a command. Then uses this environment to evaluate the permissions and then evaluate the command.
Diffstat (limited to 'cli/args')
-rw-r--r--cli/args/flags.rs82
1 files changed, 65 insertions, 17 deletions
diff --git a/cli/args/flags.rs b/cli/args/flags.rs
index 257bf8178..5ea8b8ecf 100644
--- a/cli/args/flags.rs
+++ b/cli/args/flags.rs
@@ -1,7 +1,16 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-use crate::args::resolve_no_prompt;
-use crate::util::fs::canonicalize_path;
+use std::collections::HashSet;
+use std::env;
+use std::ffi::OsString;
+use std::net::SocketAddr;
+use std::num::NonZeroU32;
+use std::num::NonZeroU8;
+use std::num::NonZeroUsize;
+use std::path::Path;
+use std::path::PathBuf;
+use std::str::FromStr;
+
use clap::builder::styling::AnsiColor;
use clap::builder::FalseyValueParser;
use clap::error::ErrorKind;
@@ -23,22 +32,16 @@ use deno_core::normalize_path;
use deno_core::resolve_url_or_path;
use deno_core::url::Url;
use deno_graph::GraphKind;
+use deno_runtime::colors;
use deno_runtime::deno_permissions::parse_sys_kind;
use deno_runtime::deno_permissions::PermissionsOptions;
use log::debug;
use log::Level;
use serde::Deserialize;
use serde::Serialize;
-use std::collections::HashSet;
-use std::env;
-use std::ffi::OsString;
-use std::net::SocketAddr;
-use std::num::NonZeroU32;
-use std::num::NonZeroU8;
-use std::num::NonZeroUsize;
-use std::path::Path;
-use std::path::PathBuf;
-use std::str::FromStr;
+
+use crate::args::resolve_no_prompt;
+use crate::util::fs::canonicalize_path;
use super::flags_net;
@@ -681,6 +684,54 @@ impl PermissionFlags {
Ok(Some(new_paths))
}
+ fn resolve_allow_run(
+ allow_run: &[String],
+ ) -> Result<Vec<PathBuf>, AnyError> {
+ let mut new_allow_run = Vec::with_capacity(allow_run.len());
+ for command_name in allow_run {
+ if command_name.is_empty() {
+ bail!("Empty command name not allowed in --allow-run=...")
+ }
+ let command_path_result = which::which(command_name);
+ match command_path_result {
+ Ok(command_path) => new_allow_run.push(command_path),
+ Err(err) => {
+ log::info!(
+ "{} Failed to resolve '{}' for allow-run: {}",
+ colors::gray("Info"),
+ command_name,
+ err
+ );
+ }
+ }
+ }
+ Ok(new_allow_run)
+ }
+
+ let mut deny_write =
+ convert_option_str_to_path_buf(&self.deny_write, initial_cwd)?;
+ let allow_run = self
+ .allow_run
+ .as_ref()
+ .and_then(|raw_allow_run| match resolve_allow_run(raw_allow_run) {
+ Ok(resolved_allow_run) => {
+ if resolved_allow_run.is_empty() && !raw_allow_run.is_empty() {
+ None // convert to no permissions if now empty
+ } else {
+ Some(Ok(resolved_allow_run))
+ }
+ }
+ Err(err) => Some(Err(err)),
+ })
+ .transpose()?;
+ // add the allow_run list to deno_write
+ if let Some(allow_run_vec) = &allow_run {
+ if !allow_run_vec.is_empty() {
+ let deno_write = deny_write.get_or_insert_with(Vec::new);
+ deno_write.extend(allow_run_vec.iter().cloned());
+ }
+ }
+
Ok(PermissionsOptions {
allow_all: self.allow_all,
allow_env: self.allow_env.clone(),
@@ -694,7 +745,7 @@ impl PermissionFlags {
initial_cwd,
)?,
deny_read: convert_option_str_to_path_buf(&self.deny_read, initial_cwd)?,
- allow_run: self.allow_run.clone(),
+ allow_run,
deny_run: self.deny_run.clone(),
allow_sys: self.allow_sys.clone(),
deny_sys: self.deny_sys.clone(),
@@ -702,10 +753,7 @@ impl PermissionFlags {
&self.allow_write,
initial_cwd,
)?,
- deny_write: convert_option_str_to_path_buf(
- &self.deny_write,
- initial_cwd,
- )?,
+ deny_write,
prompt: !resolve_no_prompt(self),
})
}