Move to allowlist and blocklist (#6282)

This commit is contained in:
Luca Casonato 2020-06-13 19:09:39 +02:00 committed by GitHub
parent 77545219a6
commit 0ffc99a61d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 137 additions and 132 deletions

View file

@ -64,7 +64,7 @@ const SUPPORTED_URL_SCHEMES: [&str; 3] = ["http", "https", "file"];
#[derive(Clone)] #[derive(Clone)]
pub struct SourceFileFetcher { pub struct SourceFileFetcher {
source_file_cache: SourceFileCache, source_file_cache: SourceFileCache,
cache_blacklist: Vec<String>, cache_blocklist: Vec<String>,
use_disk_cache: bool, use_disk_cache: bool,
no_remote: bool, no_remote: bool,
cached_only: bool, cached_only: bool,
@ -77,7 +77,7 @@ impl SourceFileFetcher {
pub fn new( pub fn new(
http_cache: HttpCache, http_cache: HttpCache,
use_disk_cache: bool, use_disk_cache: bool,
cache_blacklist: Vec<String>, cache_blocklist: Vec<String>,
no_remote: bool, no_remote: bool,
cached_only: bool, cached_only: bool,
ca_file: Option<String>, ca_file: Option<String>,
@ -85,7 +85,7 @@ impl SourceFileFetcher {
let file_fetcher = Self { let file_fetcher = Self {
http_cache, http_cache,
source_file_cache: SourceFileCache::default(), source_file_cache: SourceFileCache::default(),
cache_blacklist, cache_blocklist,
use_disk_cache, use_disk_cache,
no_remote, no_remote,
cached_only, cached_only,
@ -426,10 +426,10 @@ impl SourceFileFetcher {
return futures::future::err(e.into()).boxed_local(); return futures::future::err(e.into()).boxed_local();
} }
let is_blacklisted = let is_blocked =
check_cache_blacklist(module_url, self.cache_blacklist.as_ref()); check_cache_blocklist(module_url, self.cache_blocklist.as_ref());
// First try local cache // First try local cache
if use_disk_cache && !is_blacklisted { if use_disk_cache && !is_blocked {
match self.fetch_cached_remote_source(&module_url) { match self.fetch_cached_remote_source(&module_url) {
Ok(Some(source_file)) => { Ok(Some(source_file)) => {
return futures::future::ok(source_file).boxed_local(); return futures::future::ok(source_file).boxed_local();
@ -655,7 +655,7 @@ fn filter_shebang(bytes: Vec<u8>) -> Vec<u8> {
} }
} }
fn check_cache_blacklist(url: &Url, black_list: &[String]) -> bool { fn check_cache_blocklist(url: &Url, black_list: &[String]) -> bool {
let mut url_without_fragmets = url.clone(); let mut url_without_fragmets = url.clone();
url_without_fragmets.set_fragment(None); url_without_fragmets.set_fragment(None);
if black_list.contains(&String::from(url_without_fragmets.as_str())) { if black_list.contains(&String::from(url_without_fragmets.as_str())) {
@ -725,7 +725,7 @@ mod tests {
} }
#[test] #[test]
fn test_cache_blacklist() { fn test_cache_blocklist() {
let args = crate::flags::resolve_urls(vec![ let args = crate::flags::resolve_urls(vec![
String::from("http://deno.land/std"), String::from("http://deno.land/std"),
String::from("http://github.com/example/mod.ts"), String::from("http://github.com/example/mod.ts"),
@ -735,52 +735,52 @@ mod tests {
]); ]);
let u: Url = "http://deno.land/std/fs/mod.ts".parse().unwrap(); let u: Url = "http://deno.land/std/fs/mod.ts".parse().unwrap();
assert_eq!(check_cache_blacklist(&u, &args), true); assert_eq!(check_cache_blocklist(&u, &args), true);
let u: Url = "http://github.com/example/file.ts".parse().unwrap(); let u: Url = "http://github.com/example/file.ts".parse().unwrap();
assert_eq!(check_cache_blacklist(&u, &args), false); assert_eq!(check_cache_blocklist(&u, &args), false);
let u: Url = "http://github.com/example/mod.ts".parse().unwrap(); let u: Url = "http://github.com/example/mod.ts".parse().unwrap();
assert_eq!(check_cache_blacklist(&u, &args), true); assert_eq!(check_cache_blocklist(&u, &args), true);
let u: Url = "http://github.com/example/mod.ts?foo=bar".parse().unwrap(); let u: Url = "http://github.com/example/mod.ts?foo=bar".parse().unwrap();
assert_eq!(check_cache_blacklist(&u, &args), true); assert_eq!(check_cache_blocklist(&u, &args), true);
let u: Url = "http://github.com/example/mod.ts#fragment".parse().unwrap(); let u: Url = "http://github.com/example/mod.ts#fragment".parse().unwrap();
assert_eq!(check_cache_blacklist(&u, &args), true); assert_eq!(check_cache_blocklist(&u, &args), true);
let u: Url = "http://fragment.com/mod.ts".parse().unwrap(); let u: Url = "http://fragment.com/mod.ts".parse().unwrap();
assert_eq!(check_cache_blacklist(&u, &args), true); assert_eq!(check_cache_blocklist(&u, &args), true);
let u: Url = "http://query.com/mod.ts".parse().unwrap(); let u: Url = "http://query.com/mod.ts".parse().unwrap();
assert_eq!(check_cache_blacklist(&u, &args), false); assert_eq!(check_cache_blocklist(&u, &args), false);
let u: Url = "http://fragment.com/mod.ts#fragment".parse().unwrap(); let u: Url = "http://fragment.com/mod.ts#fragment".parse().unwrap();
assert_eq!(check_cache_blacklist(&u, &args), true); assert_eq!(check_cache_blocklist(&u, &args), true);
let u: Url = "http://query.com/mod.ts?foo=bar".parse().unwrap(); let u: Url = "http://query.com/mod.ts?foo=bar".parse().unwrap();
assert_eq!(check_cache_blacklist(&u, &args), true); assert_eq!(check_cache_blocklist(&u, &args), true);
let u: Url = "http://queryandfragment.com/mod.ts".parse().unwrap(); let u: Url = "http://queryandfragment.com/mod.ts".parse().unwrap();
assert_eq!(check_cache_blacklist(&u, &args), false); assert_eq!(check_cache_blocklist(&u, &args), false);
let u: Url = "http://queryandfragment.com/mod.ts?foo=bar" let u: Url = "http://queryandfragment.com/mod.ts?foo=bar"
.parse() .parse()
.unwrap(); .unwrap();
assert_eq!(check_cache_blacklist(&u, &args), true); assert_eq!(check_cache_blocklist(&u, &args), true);
let u: Url = "http://queryandfragment.com/mod.ts#fragment" let u: Url = "http://queryandfragment.com/mod.ts#fragment"
.parse() .parse()
.unwrap(); .unwrap();
assert_eq!(check_cache_blacklist(&u, &args), false); assert_eq!(check_cache_blocklist(&u, &args), false);
let u: Url = "http://query.com/mod.ts?foo=bar#fragment".parse().unwrap(); let u: Url = "http://query.com/mod.ts?foo=bar#fragment".parse().unwrap();
assert_eq!(check_cache_blacklist(&u, &args), true); assert_eq!(check_cache_blocklist(&u, &args), true);
let u: Url = "http://fragment.com/mod.ts?foo=bar#fragment" let u: Url = "http://fragment.com/mod.ts?foo=bar#fragment"
.parse() .parse()
.unwrap(); .unwrap();
assert_eq!(check_cache_blacklist(&u, &args), true); assert_eq!(check_cache_blocklist(&u, &args), true);
} }
#[test] #[test]

View file

@ -93,7 +93,7 @@ pub struct Flags {
pub allow_read: bool, pub allow_read: bool,
pub allow_run: bool, pub allow_run: bool,
pub allow_write: bool, pub allow_write: bool,
pub cache_blacklist: Vec<String>, pub cache_blocklist: Vec<String>,
pub ca_file: Option<String>, pub ca_file: Option<String>,
pub cached_only: bool, pub cached_only: bool,
pub config_path: Option<String>, pub config_path: Option<String>,
@ -103,20 +103,20 @@ pub struct Flags {
pub lock: Option<String>, pub lock: Option<String>,
pub lock_write: bool, pub lock_write: bool,
pub log_level: Option<Level>, pub log_level: Option<Level>,
pub net_whitelist: Vec<String>, pub net_allowlist: Vec<String>,
pub no_prompts: bool, pub no_prompts: bool,
pub no_remote: bool, pub no_remote: bool,
pub read_whitelist: Vec<PathBuf>, pub read_allowlist: Vec<PathBuf>,
pub reload: bool, pub reload: bool,
pub seed: Option<u64>, pub seed: Option<u64>,
pub unstable: bool, pub unstable: bool,
pub v8_flags: Option<Vec<String>>, pub v8_flags: Option<Vec<String>>,
pub version: bool, pub version: bool,
pub write_whitelist: Vec<PathBuf>, pub write_allowlist: Vec<PathBuf>,
} }
fn join_paths(whitelist: &[PathBuf], d: &str) -> String { fn join_paths(allowlist: &[PathBuf], d: &str) -> String {
whitelist allowlist
.iter() .iter()
.map(|path| path.to_str().unwrap().to_string()) .map(|path| path.to_str().unwrap().to_string())
.collect::<Vec<String>>() .collect::<Vec<String>>()
@ -129,8 +129,8 @@ impl Flags {
pub fn to_permission_args(&self) -> Vec<String> { pub fn to_permission_args(&self) -> Vec<String> {
let mut args = vec![]; let mut args = vec![];
if !self.read_whitelist.is_empty() { if !self.read_allowlist.is_empty() {
let s = format!("--allow-read={}", join_paths(&self.read_whitelist, ",")); let s = format!("--allow-read={}", join_paths(&self.read_allowlist, ","));
args.push(s); args.push(s);
} }
@ -138,9 +138,9 @@ impl Flags {
args.push("--allow-read".to_string()); args.push("--allow-read".to_string());
} }
if !self.write_whitelist.is_empty() { if !self.write_allowlist.is_empty() {
let s = let s =
format!("--allow-write={}", join_paths(&self.write_whitelist, ",")); format!("--allow-write={}", join_paths(&self.write_allowlist, ","));
args.push(s); args.push(s);
} }
@ -148,8 +148,8 @@ impl Flags {
args.push("--allow-write".to_string()); args.push("--allow-write".to_string());
} }
if !self.net_whitelist.is_empty() { if !self.net_allowlist.is_empty() {
let s = format!("--allow-net={}", self.net_whitelist.join(",")); let s = format!("--allow-net={}", self.net_allowlist.join(","));
args.push(s); args.push(s);
} }
@ -1051,7 +1051,7 @@ Grant all permissions:
Grant permission to read from disk and listen to network: Grant permission to read from disk and listen to network:
deno run --allow-read --allow-net https://deno.land/std/http/file_server.ts deno run --allow-read --allow-net https://deno.land/std/http/file_server.ts
Grant permission to read whitelisted files from disk: Grant permission to read allow-listed files from disk:
deno run --allow-read=/etc https://deno.land/std/http/file_server.ts deno run --allow-read=/etc https://deno.land/std/http/file_server.ts
Deno allows specifying the filename '-' to read the file from stdin. Deno allows specifying the filename '-' to read the file from stdin.
@ -1224,7 +1224,7 @@ fn reload_arg<'a, 'b>() -> Arg<'a, 'b> {
.require_equals(true) .require_equals(true)
.long("reload") .long("reload")
.help("Reload source code cache (recompile TypeScript)") .help("Reload source code cache (recompile TypeScript)")
.value_name("CACHE_BLACKLIST") .value_name("CACHE_BLOCKLIST")
.long_help( .long_help(
"Reload source code cache (recompile TypeScript) "Reload source code cache (recompile TypeScript)
--reload --reload
@ -1238,13 +1238,13 @@ fn reload_arg<'a, 'b>() -> Arg<'a, 'b> {
fn reload_arg_parse(flags: &mut Flags, matches: &ArgMatches) { fn reload_arg_parse(flags: &mut Flags, matches: &ArgMatches) {
if let Some(cache_bl) = matches.values_of("reload") { if let Some(cache_bl) = matches.values_of("reload") {
let raw_cache_blacklist: Vec<String> = let raw_cache_blocklist: Vec<String> =
cache_bl.map(std::string::ToString::to_string).collect(); cache_bl.map(std::string::ToString::to_string).collect();
if raw_cache_blacklist.is_empty() { if raw_cache_blocklist.is_empty() {
flags.reload = true; flags.reload = true;
} else { } else {
flags.cache_blacklist = resolve_urls(raw_cache_blacklist); flags.cache_blocklist = resolve_urls(raw_cache_blocklist);
debug!("cache blacklist: {:#?}", &flags.cache_blacklist); debug!("cache blocklist: {:#?}", &flags.cache_blocklist);
flags.reload = false; flags.reload = false;
} }
} }
@ -1299,33 +1299,33 @@ fn no_remote_arg_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
fn permission_args_parse(flags: &mut Flags, matches: &clap::ArgMatches) { fn permission_args_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
if let Some(read_wl) = matches.values_of("allow-read") { if let Some(read_wl) = matches.values_of("allow-read") {
let read_whitelist: Vec<PathBuf> = read_wl.map(PathBuf::from).collect(); let read_allowlist: Vec<PathBuf> = read_wl.map(PathBuf::from).collect();
if read_whitelist.is_empty() { if read_allowlist.is_empty() {
flags.allow_read = true; flags.allow_read = true;
} else { } else {
flags.read_whitelist = read_whitelist; flags.read_allowlist = read_allowlist;
} }
} }
if let Some(write_wl) = matches.values_of("allow-write") { if let Some(write_wl) = matches.values_of("allow-write") {
let write_whitelist: Vec<PathBuf> = write_wl.map(PathBuf::from).collect(); let write_allowlist: Vec<PathBuf> = write_wl.map(PathBuf::from).collect();
if write_whitelist.is_empty() { if write_allowlist.is_empty() {
flags.allow_write = true; flags.allow_write = true;
} else { } else {
flags.write_whitelist = write_whitelist; flags.write_allowlist = write_allowlist;
} }
} }
if let Some(net_wl) = matches.values_of("allow-net") { if let Some(net_wl) = matches.values_of("allow-net") {
let raw_net_whitelist: Vec<String> = let raw_net_allowlist: Vec<String> =
net_wl.map(std::string::ToString::to_string).collect(); net_wl.map(std::string::ToString::to_string).collect();
if raw_net_whitelist.is_empty() { if raw_net_allowlist.is_empty() {
flags.allow_net = true; flags.allow_net = true;
} else { } else {
flags.net_whitelist = resolve_hosts(raw_net_whitelist); flags.net_allowlist = resolve_hosts(raw_net_allowlist);
debug!("net whitelist: {:#?}", &flags.net_whitelist); debug!("net allowlist: {:#?}", &flags.net_allowlist);
} }
} }
@ -1974,7 +1974,7 @@ mod tests {
} }
#[test] #[test]
fn allow_read_whitelist() { fn allow_read_allowlist() {
use tempfile::TempDir; use tempfile::TempDir;
let temp_dir = TempDir::new().expect("tempdir fail").path().to_path_buf(); let temp_dir = TempDir::new().expect("tempdir fail").path().to_path_buf();
@ -1988,7 +1988,7 @@ mod tests {
r.unwrap(), r.unwrap(),
Flags { Flags {
allow_read: false, allow_read: false,
read_whitelist: vec![PathBuf::from("."), temp_dir], read_allowlist: vec![PathBuf::from("."), temp_dir],
subcommand: DenoSubcommand::Run { subcommand: DenoSubcommand::Run {
script: "script.ts".to_string(), script: "script.ts".to_string(),
}, },
@ -1998,7 +1998,7 @@ mod tests {
} }
#[test] #[test]
fn allow_write_whitelist() { fn allow_write_allowlist() {
use tempfile::TempDir; use tempfile::TempDir;
let temp_dir = TempDir::new().expect("tempdir fail").path().to_path_buf(); let temp_dir = TempDir::new().expect("tempdir fail").path().to_path_buf();
@ -2012,7 +2012,7 @@ mod tests {
r.unwrap(), r.unwrap(),
Flags { Flags {
allow_write: false, allow_write: false,
write_whitelist: vec![PathBuf::from("."), temp_dir], write_allowlist: vec![PathBuf::from("."), temp_dir],
subcommand: DenoSubcommand::Run { subcommand: DenoSubcommand::Run {
script: "script.ts".to_string(), script: "script.ts".to_string(),
}, },
@ -2022,7 +2022,7 @@ mod tests {
} }
#[test] #[test]
fn allow_net_whitelist() { fn allow_net_allowlist() {
let r = flags_from_vec_safe(svec![ let r = flags_from_vec_safe(svec![
"deno", "deno",
"run", "run",
@ -2036,7 +2036,7 @@ mod tests {
script: "script.ts".to_string(), script: "script.ts".to_string(),
}, },
allow_net: false, allow_net: false,
net_whitelist: svec!["127.0.0.1"], net_allowlist: svec!["127.0.0.1"],
..Flags::default() ..Flags::default()
} }
); );
@ -2454,7 +2454,7 @@ mod tests {
} }
#[test] #[test]
fn allow_net_whitelist_with_ports() { fn allow_net_allowlist_with_ports() {
let r = flags_from_vec_safe(svec![ let r = flags_from_vec_safe(svec![
"deno", "deno",
"run", "run",
@ -2467,7 +2467,7 @@ mod tests {
subcommand: DenoSubcommand::Run { subcommand: DenoSubcommand::Run {
script: "script.ts".to_string(), script: "script.ts".to_string(),
}, },
net_whitelist: svec![ net_allowlist: svec![
"deno.land", "deno.land",
"0.0.0.0:8000", "0.0.0.0:8000",
"127.0.0.1:8000", "127.0.0.1:8000",

View file

@ -61,7 +61,7 @@ impl GlobalState {
let file_fetcher = SourceFileFetcher::new( let file_fetcher = SourceFileFetcher::new(
http_cache, http_cache,
!flags.reload, !flags.reload,
flags.cache_blacklist.clone(), flags.cache_blocklist.clone(),
flags.no_remote, flags.no_remote,
flags.cached_only, flags.cached_only,
flags.ca_file.clone(), flags.ca_file.clone(),

View file

@ -146,13 +146,13 @@ pub struct Permissions {
// Keep in sync with cli/js/permissions.ts // Keep in sync with cli/js/permissions.ts
#[serde(deserialize_with = "deserialize_permission_state")] #[serde(deserialize_with = "deserialize_permission_state")]
pub allow_read: PermissionState, pub allow_read: PermissionState,
pub read_whitelist: HashSet<PathBuf>, pub read_allowlist: HashSet<PathBuf>,
#[serde(deserialize_with = "deserialize_permission_state")] #[serde(deserialize_with = "deserialize_permission_state")]
pub allow_write: PermissionState, pub allow_write: PermissionState,
pub write_whitelist: HashSet<PathBuf>, pub write_allowlist: HashSet<PathBuf>,
#[serde(deserialize_with = "deserialize_permission_state")] #[serde(deserialize_with = "deserialize_permission_state")]
pub allow_net: PermissionState, pub allow_net: PermissionState,
pub net_whitelist: HashSet<String>, pub net_allowlist: HashSet<String>,
#[serde(deserialize_with = "deserialize_permission_state")] #[serde(deserialize_with = "deserialize_permission_state")]
pub allow_env: PermissionState, pub allow_env: PermissionState,
#[serde(deserialize_with = "deserialize_permission_state")] #[serde(deserialize_with = "deserialize_permission_state")]
@ -163,8 +163,8 @@ pub struct Permissions {
pub allow_hrtime: PermissionState, pub allow_hrtime: PermissionState,
} }
fn resolve_fs_whitelist(whitelist: &[PathBuf]) -> HashSet<PathBuf> { fn resolve_fs_allowlist(allowlist: &[PathBuf]) -> HashSet<PathBuf> {
whitelist allowlist
.iter() .iter()
.map(|raw_path| resolve_from_cwd(Path::new(&raw_path)).unwrap()) .map(|raw_path| resolve_from_cwd(Path::new(&raw_path)).unwrap())
.collect() .collect()
@ -174,11 +174,11 @@ impl Permissions {
pub fn from_flags(flags: &Flags) -> Self { pub fn from_flags(flags: &Flags) -> Self {
Self { Self {
allow_read: PermissionState::from(flags.allow_read), allow_read: PermissionState::from(flags.allow_read),
read_whitelist: resolve_fs_whitelist(&flags.read_whitelist), read_allowlist: resolve_fs_allowlist(&flags.read_allowlist),
allow_write: PermissionState::from(flags.allow_write), allow_write: PermissionState::from(flags.allow_write),
write_whitelist: resolve_fs_whitelist(&flags.write_whitelist), write_allowlist: resolve_fs_allowlist(&flags.write_allowlist),
allow_net: PermissionState::from(flags.allow_net), allow_net: PermissionState::from(flags.allow_net),
net_whitelist: flags.net_whitelist.iter().cloned().collect(), net_allowlist: flags.net_allowlist.iter().cloned().collect(),
allow_env: PermissionState::from(flags.allow_env), allow_env: PermissionState::from(flags.allow_env),
allow_run: PermissionState::from(flags.allow_run), allow_run: PermissionState::from(flags.allow_run),
allow_plugin: PermissionState::from(flags.allow_plugin), allow_plugin: PermissionState::from(flags.allow_plugin),
@ -224,7 +224,7 @@ impl Permissions {
} }
fn get_state_read(&self, path: &Option<&Path>) -> PermissionState { fn get_state_read(&self, path: &Option<&Path>) -> PermissionState {
if path.map_or(false, |f| check_path_white_list(f, &self.read_whitelist)) { if path.map_or(false, |f| check_path_white_list(f, &self.read_allowlist)) {
return PermissionState::Allow; return PermissionState::Allow;
} }
self.allow_read self.allow_read
@ -252,7 +252,7 @@ impl Permissions {
} }
fn get_state_write(&self, path: &Option<&Path>) -> PermissionState { fn get_state_write(&self, path: &Option<&Path>) -> PermissionState {
if path.map_or(false, |f| check_path_white_list(f, &self.write_whitelist)) { if path.map_or(false, |f| check_path_white_list(f, &self.write_allowlist)) {
return PermissionState::Allow; return PermissionState::Allow;
} }
self.allow_write self.allow_write
@ -267,7 +267,7 @@ impl Permissions {
} }
fn get_state_net(&self, host: &str, port: Option<u16>) -> PermissionState { fn get_state_net(&self, host: &str, port: Option<u16>) -> PermissionState {
if check_host_and_port_whitelist(host, port, &self.net_whitelist) { if check_host_and_port_allowlist(host, port, &self.net_allowlist) {
return PermissionState::Allow; return PermissionState::Allow;
} }
self.allow_net self.allow_net
@ -327,7 +327,7 @@ impl Permissions {
pub fn request_read(&mut self, path: &Option<&Path>) -> PermissionState { pub fn request_read(&mut self, path: &Option<&Path>) -> PermissionState {
let paths = path.map(|p| self.resolved_and_display_path(p)); let paths = path.map(|p| self.resolved_and_display_path(p));
if let Some((p, _)) = paths.as_ref() { if let Some((p, _)) = paths.as_ref() {
if check_path_white_list(&p, &self.read_whitelist) { if check_path_white_list(&p, &self.read_allowlist) {
return PermissionState::Allow; return PermissionState::Allow;
} }
}; };
@ -343,7 +343,7 @@ impl Permissions {
pub fn request_write(&mut self, path: &Option<&Path>) -> PermissionState { pub fn request_write(&mut self, path: &Option<&Path>) -> PermissionState {
let paths = path.map(|p| self.resolved_and_display_path(p)); let paths = path.map(|p| self.resolved_and_display_path(p));
if let Some((p, _)) = paths.as_ref() { if let Some((p, _)) = paths.as_ref() {
if check_path_white_list(&p, &self.write_whitelist) { if check_path_white_list(&p, &self.write_allowlist) {
return PermissionState::Allow; return PermissionState::Allow;
} }
}; };
@ -409,11 +409,11 @@ impl Permissions {
pub fn fork( pub fn fork(
&self, &self,
allow_read: bool, allow_read: bool,
read_whitelist: HashSet<PathBuf>, read_allowlist: HashSet<PathBuf>,
allow_write: bool, allow_write: bool,
write_whitelist: HashSet<PathBuf>, write_allowlist: HashSet<PathBuf>,
allow_net: bool, allow_net: bool,
net_whitelist: HashSet<String>, net_allowlist: HashSet<String>,
allow_env: bool, allow_env: bool,
allow_run: bool, allow_run: bool,
allow_plugin: bool, allow_plugin: bool,
@ -426,29 +426,29 @@ impl Permissions {
let allow_run = self.allow_run.fork(allow_run)?; let allow_run = self.allow_run.fork(allow_run)?;
let allow_plugin = self.allow_plugin.fork(allow_plugin)?; let allow_plugin = self.allow_plugin.fork(allow_plugin)?;
let allow_hrtime = self.allow_hrtime.fork(allow_hrtime)?; let allow_hrtime = self.allow_hrtime.fork(allow_hrtime)?;
if !(read_whitelist.is_subset(&self.read_whitelist)) { if !(read_allowlist.is_subset(&self.read_allowlist)) {
Err(OpError::permission_denied(format!( Err(OpError::permission_denied(format!(
"Arguments escalate parent permissions. Parent Permissions have only {:?} in `read_whitelist`", "Arguments escalate parent permissions. Parent Permissions have only {:?} in `read_allowlist`",
self.read_whitelist self.read_allowlist
))) )))
} else if !(write_whitelist.is_subset(&self.write_whitelist)) { } else if !(write_allowlist.is_subset(&self.write_allowlist)) {
Err(OpError::permission_denied(format!( Err(OpError::permission_denied(format!(
"Arguments escalate parent permissions. Parent Permissions have only {:?} in `write_whitelist`", "Arguments escalate parent permissions. Parent Permissions have only {:?} in `write_allowlist`",
self.write_whitelist self.write_allowlist
))) )))
} else if !(net_whitelist.is_subset(&self.net_whitelist)) { } else if !(net_allowlist.is_subset(&self.net_allowlist)) {
Err(OpError::permission_denied(format!( Err(OpError::permission_denied(format!(
"Arguments escalate parent permissions. Parent Permissions have only {:?} in `net_whitelist`", "Arguments escalate parent permissions. Parent Permissions have only {:?} in `net_allowlist`",
self.net_whitelist self.net_allowlist
))) )))
} else { } else {
Ok(Permissions { Ok(Permissions {
allow_read, allow_read,
read_whitelist, read_allowlist,
allow_write, allow_write,
write_whitelist, write_allowlist,
allow_net, allow_net,
net_whitelist, net_allowlist,
allow_env, allow_env,
allow_run, allow_run,
allow_plugin, allow_plugin,
@ -533,14 +533,14 @@ fn check_path_white_list(path: &Path, white_list: &HashSet<PathBuf>) -> bool {
false false
} }
fn check_host_and_port_whitelist( fn check_host_and_port_allowlist(
host: &str, host: &str,
port: Option<u16>, port: Option<u16>,
whitelist: &HashSet<String>, allowlist: &HashSet<String>,
) -> bool { ) -> bool {
whitelist.contains(host) allowlist.contains(host)
|| (port.is_some() || (port.is_some()
&& whitelist.contains(&format!("{}:{}", host, port.unwrap()))) && allowlist.contains(&format!("{}:{}", host, port.unwrap())))
} }
#[cfg(test)] #[cfg(test)]
@ -554,15 +554,15 @@ mod tests {
#[test] #[test]
fn check_paths() { fn check_paths() {
let whitelist = vec![ let allowlist = vec![
PathBuf::from("/a/specific/dir/name"), PathBuf::from("/a/specific/dir/name"),
PathBuf::from("/a/specific"), PathBuf::from("/a/specific"),
PathBuf::from("/b/c"), PathBuf::from("/b/c"),
]; ];
let perms = Permissions::from_flags(&Flags { let perms = Permissions::from_flags(&Flags {
read_whitelist: whitelist.clone(), read_allowlist: allowlist.clone(),
write_whitelist: whitelist, write_allowlist: allowlist,
..Default::default() ..Default::default()
}); });
@ -616,7 +616,7 @@ mod tests {
#[test] #[test]
fn test_check_net() { fn test_check_net() {
let perms = Permissions::from_flags(&Flags { let perms = Permissions::from_flags(&Flags {
net_whitelist: svec![ net_allowlist: svec![
"localhost", "localhost",
"deno.land", "deno.land",
"github.com:3000", "github.com:3000",
@ -716,13 +716,13 @@ mod tests {
#[test] #[test]
fn test_permissions_request_read() { fn test_permissions_request_read() {
let guard = PERMISSION_PROMPT_GUARD.lock().unwrap(); let guard = PERMISSION_PROMPT_GUARD.lock().unwrap();
let whitelist = vec![PathBuf::from("/foo/bar")]; let allowlist = vec![PathBuf::from("/foo/bar")];
let mut perms0 = Permissions::from_flags(&Flags { let mut perms0 = Permissions::from_flags(&Flags {
read_whitelist: whitelist.clone(), read_allowlist: allowlist.clone(),
..Default::default() ..Default::default()
}); });
set_prompt_result(false); set_prompt_result(false);
// If the whitelist contains the path, then the result is `allow` // If the allowlist contains the path, then the result is `allow`
// regardless of prompt result // regardless of prompt result
assert_eq!( assert_eq!(
perms0.request_read(&Some(Path::new("/foo/bar"))), perms0.request_read(&Some(Path::new("/foo/bar"))),
@ -730,7 +730,7 @@ mod tests {
); );
let mut perms1 = Permissions::from_flags(&Flags { let mut perms1 = Permissions::from_flags(&Flags {
read_whitelist: whitelist.clone(), read_allowlist: allowlist.clone(),
..Default::default() ..Default::default()
}); });
set_prompt_result(true); set_prompt_result(true);
@ -740,7 +740,7 @@ mod tests {
); );
let mut perms2 = Permissions::from_flags(&Flags { let mut perms2 = Permissions::from_flags(&Flags {
read_whitelist: whitelist, read_allowlist: allowlist,
..Default::default() ..Default::default()
}); });
set_prompt_result(false); set_prompt_result(false);
@ -754,13 +754,13 @@ mod tests {
#[test] #[test]
fn test_permissions_request_write() { fn test_permissions_request_write() {
let guard = PERMISSION_PROMPT_GUARD.lock().unwrap(); let guard = PERMISSION_PROMPT_GUARD.lock().unwrap();
let whitelist = vec![PathBuf::from("/foo/bar")]; let allowlist = vec![PathBuf::from("/foo/bar")];
let mut perms0 = Permissions::from_flags(&Flags { let mut perms0 = Permissions::from_flags(&Flags {
write_whitelist: whitelist.clone(), write_allowlist: allowlist.clone(),
..Default::default() ..Default::default()
}); });
set_prompt_result(false); set_prompt_result(false);
// If the whitelist contains the path, then the result is `allow` // If the allowlist contains the path, then the result is `allow`
// regardless of prompt result // regardless of prompt result
assert_eq!( assert_eq!(
perms0.request_write(&Some(Path::new("/foo/bar"))), perms0.request_write(&Some(Path::new("/foo/bar"))),
@ -768,7 +768,7 @@ mod tests {
); );
let mut perms1 = Permissions::from_flags(&Flags { let mut perms1 = Permissions::from_flags(&Flags {
write_whitelist: whitelist.clone(), write_allowlist: allowlist.clone(),
..Default::default() ..Default::default()
}); });
set_prompt_result(true); set_prompt_result(true);
@ -778,7 +778,7 @@ mod tests {
); );
let mut perms2 = Permissions::from_flags(&Flags { let mut perms2 = Permissions::from_flags(&Flags {
write_whitelist: whitelist, write_allowlist: allowlist,
..Default::default() ..Default::default()
}); });
set_prompt_result(false); set_prompt_result(false);
@ -792,14 +792,14 @@ mod tests {
#[test] #[test]
fn test_permission_request_net() { fn test_permission_request_net() {
let guard = PERMISSION_PROMPT_GUARD.lock().unwrap(); let guard = PERMISSION_PROMPT_GUARD.lock().unwrap();
let whitelist = svec!["localhost:8080"]; let allowlist = svec!["localhost:8080"];
let mut perms0 = Permissions::from_flags(&Flags { let mut perms0 = Permissions::from_flags(&Flags {
net_whitelist: whitelist.clone(), net_allowlist: allowlist.clone(),
..Default::default() ..Default::default()
}); });
set_prompt_result(false); set_prompt_result(false);
// If the url matches the whitelist item, then the result is `allow` // If the url matches the allowlist item, then the result is `allow`
// regardless of prompt result // regardless of prompt result
assert_eq!( assert_eq!(
perms0 perms0
@ -809,7 +809,7 @@ mod tests {
); );
let mut perms1 = Permissions::from_flags(&Flags { let mut perms1 = Permissions::from_flags(&Flags {
net_whitelist: whitelist.clone(), net_allowlist: allowlist.clone(),
..Default::default() ..Default::default()
}); });
set_prompt_result(true); set_prompt_result(true);
@ -821,7 +821,7 @@ mod tests {
); );
let mut perms2 = Permissions::from_flags(&Flags { let mut perms2 = Permissions::from_flags(&Flags {
net_whitelist: whitelist.clone(), net_allowlist: allowlist.clone(),
..Default::default() ..Default::default()
}); });
set_prompt_result(false); set_prompt_result(false);
@ -833,7 +833,7 @@ mod tests {
); );
let mut perms3 = Permissions::from_flags(&Flags { let mut perms3 = Permissions::from_flags(&Flags {
net_whitelist: whitelist, net_allowlist: allowlist,
..Default::default() ..Default::default()
}); });
set_prompt_result(true); set_prompt_result(true);
@ -897,11 +897,11 @@ mod tests {
let json_perms = r#" let json_perms = r#"
{ {
"allow_read": true, "allow_read": true,
"read_whitelist": [], "read_allowlist": [],
"allow_write": true, "allow_write": true,
"write_whitelist": [], "write_allowlist": [],
"allow_net": true, "allow_net": true,
"net_whitelist": [], "net_allowlist": [],
"allow_env": true, "allow_env": true,
"allow_run": true, "allow_run": true,
"allow_plugin": true, "allow_plugin": true,
@ -916,9 +916,9 @@ mod tests {
allow_env: PermissionState::Allow, allow_env: PermissionState::Allow,
allow_plugin: PermissionState::Allow, allow_plugin: PermissionState::Allow,
allow_run: PermissionState::Allow, allow_run: PermissionState::Allow,
read_whitelist: HashSet::new(), read_allowlist: HashSet::new(),
write_whitelist: HashSet::new(), write_allowlist: HashSet::new(),
net_whitelist: HashSet::new(), net_allowlist: HashSet::new(),
}; };
let deserialized_perms: Permissions = let deserialized_perms: Permissions =
serde_json::from_str(json_perms).unwrap(); serde_json::from_str(json_perms).unwrap();
@ -949,11 +949,11 @@ mod tests {
.expect("Testing expect"), .expect("Testing expect"),
Permissions { Permissions {
allow_read: PermissionState::Allow, allow_read: PermissionState::Allow,
read_whitelist: HashSet::new(), read_allowlist: HashSet::new(),
allow_write: PermissionState::Allow, allow_write: PermissionState::Allow,
write_whitelist: HashSet::new(), write_allowlist: HashSet::new(),
allow_net: PermissionState::Allow, allow_net: PermissionState::Allow,
net_whitelist: HashSet::new(), net_allowlist: HashSet::new(),
allow_env: PermissionState::Allow, allow_env: PermissionState::Allow,
allow_run: PermissionState::Allow, allow_run: PermissionState::Allow,
allow_plugin: PermissionState::Deny, allow_plugin: PermissionState::Deny,
@ -978,11 +978,11 @@ mod tests {
.expect("Testing expect"), .expect("Testing expect"),
Permissions { Permissions {
allow_read: PermissionState::Allow, allow_read: PermissionState::Allow,
read_whitelist: HashSet::new(), read_allowlist: HashSet::new(),
allow_write: PermissionState::Allow, allow_write: PermissionState::Allow,
write_whitelist: HashSet::new(), write_allowlist: HashSet::new(),
allow_net: PermissionState::Allow, allow_net: PermissionState::Allow,
net_whitelist: HashSet::new(), net_allowlist: HashSet::new(),
allow_env: PermissionState::Allow, allow_env: PermissionState::Allow,
allow_run: PermissionState::Allow, allow_run: PermissionState::Allow,
allow_plugin: PermissionState::Deny, allow_plugin: PermissionState::Deny,

View file

@ -40,6 +40,11 @@ Be explicit even when it means more code.
There are some situations where it may make sense to use such techniques, but in There are some situations where it may make sense to use such techniques, but in
the vast majority of cases it does not. the vast majority of cases it does not.
## Inclusive code
Please follow the guidelines for inclusive code outlined at
https://chromium.googlesource.com/chromium/src/+/master/styleguide/inclusive_code.md.
## Rust ## Rust
Follow Rust conventions and be consistent with existing code. Follow Rust conventions and be consistent with existing code.

View file

@ -110,7 +110,7 @@ resolution, compilation configuration etc.
--config <FILE> Load tsconfig.json configuration file --config <FILE> Load tsconfig.json configuration file
--importmap <FILE> UNSTABLE: Load import map file --importmap <FILE> UNSTABLE: Load import map file
--no-remote Do not resolve remote modules --no-remote Do not resolve remote modules
--reload=<CACHE_BLACKLIST> Reload source code cache (recompile TypeScript) --reload=<CACHE_BLOCKLIST> Reload source code cache (recompile TypeScript)
--unstable Enable unstable APIs --unstable Enable unstable APIs
``` ```

View file

@ -23,26 +23,26 @@ The following permissions are available:
- **--allow-hrtime** Allow high resolution time measurement. High resolution - **--allow-hrtime** Allow high resolution time measurement. High resolution
time can be used in timing attacks and fingerprinting. time can be used in timing attacks and fingerprinting.
- **--allow-net=\<allow-net\>** Allow network access. You can specify an - **--allow-net=\<allow-net\>** Allow network access. You can specify an
optional, comma separated list of domains to provide a whitelist of allowed optional, comma separated list of domains to provide a allow-list of allowed
domains. domains.
- **--allow-plugin** Allow loading plugins. Please note that --allow-plugin is - **--allow-plugin** Allow loading plugins. Please note that --allow-plugin is
an unstable feature. an unstable feature.
- **--allow-read=\<allow-read\>** Allow file system read access. You can specify - **--allow-read=\<allow-read\>** Allow file system read access. You can specify
an optional, comma separated list of directories or files to provide a an optional, comma separated list of directories or files to provide a
whitelist of allowed file system access. allow-list of allowed file system access.
- **--allow-run** Allow running subprocesses. Be aware that subprocesses are not - **--allow-run** Allow running subprocesses. Be aware that subprocesses are not
run in a sandbox and therefore do not have the same security restrictions as run in a sandbox and therefore do not have the same security restrictions as
the deno process. Therefore, use with caution. the deno process. Therefore, use with caution.
- **--allow-write=\<allow-write\>** Allow file system write access. You can - **--allow-write=\<allow-write\>** Allow file system write access. You can
specify an optional, comma separated list of directories or files to provide a specify an optional, comma separated list of directories or files to provide a
whitelist of allowed file system access. allow-list of allowed file system access.
### Permissions whitelist ### Permissions allow-list
Deno also allows you to control the granularity of some permissions with Deno also allows you to control the granularity of some permissions with
whitelists. allow-lists.
This example restricts file system access by whitelisting only the `/usr` This example restricts file system access by allow-listing only the `/usr`
directory, however the execution fails as the process was attempting to access a directory, however the execution fails as the process was attempting to access a
file in the `/etc` directory: file in the `/etc` directory:
@ -54,7 +54,7 @@ error: Uncaught PermissionDenied: read access to "/etc/passwd", run again with t
... ...
``` ```
Try it out again with the correct permissions by whitelisting `/etc` instead: Try it out again with the correct permissions by allow-listing `/etc` instead:
```shell ```shell
deno run --allow-read=/etc https://deno.land/std/examples/cat.ts /etc/passwd deno run --allow-read=/etc https://deno.land/std/examples/cat.ts /etc/passwd
@ -70,7 +70,7 @@ _fetch.ts_:
const result = await fetch("https://deno.land/"); const result = await fetch("https://deno.land/");
``` ```
This is an example on how to whitelist hosts/urls: This is an example on how to allow-list hosts/urls:
```shell ```shell
deno run --allow-net=github.com,deno.land fetch.ts deno run --allow-net=github.com,deno.land fetch.ts