diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/ops.rs | 9 | ||||
-rw-r--r-- | cli/permissions.rs | 4 | ||||
-rw-r--r-- | cli/state.rs | 36 |
3 files changed, 43 insertions, 6 deletions
diff --git a/cli/ops.rs b/cli/ops.rs index 166610bac..7a68dee55 100644 --- a/cli/ops.rs +++ b/cli/ops.rs @@ -497,7 +497,12 @@ fn op_fetch_source_file( let specifier = inner.specifier().unwrap(); let referrer = inner.referrer().unwrap(); - let resolved_specifier = state.resolve(specifier, referrer, false)?; + // TODO(ry) Maybe a security hole. Only the compiler worker should have access + // to this. Need a test to demonstrate the hole. + let is_dyn_import = false; + + let resolved_specifier = + state.resolve(specifier, referrer, false, is_dyn_import)?; let fut = state .file_fetcher @@ -750,7 +755,7 @@ fn op_fetch( let req = msg_util::deserialize_request(header, body)?; let url_ = url::Url::parse(url).map_err(ErrBox::from)?; - state.check_net_url(url_)?; + state.check_net_url(&url_)?; let client = http_util::get_client(); diff --git a/cli/permissions.rs b/cli/permissions.rs index 9774d92c0..814c3ff94 100644 --- a/cli/permissions.rs +++ b/cli/permissions.rs @@ -274,7 +274,7 @@ impl DenoPermissions { } } - pub fn check_net_url(&self, url: url::Url) -> Result<(), ErrBox> { + pub fn check_net_url(&self, url: &url::Url) -> Result<(), ErrBox> { let msg = &format!("network access to \"{}\"", url); match self.allow_net.get_state() { PermissionAccessorState::Allow => { @@ -627,7 +627,7 @@ mod tests { for (url_str, is_ok) in url_tests.iter() { let u = url::Url::parse(url_str).unwrap(); - assert_eq!(*is_ok, perms.check_net_url(u).is_ok()); + assert_eq!(*is_ok, perms.check_net_url(&u).is_ok()); } for (domain, is_ok) in domain_tests.iter() { diff --git a/cli/state.rs b/cli/state.rs index eb912161d..0b0f3b1ae 100644 --- a/cli/state.rs +++ b/cli/state.rs @@ -4,6 +4,7 @@ use crate::compilers::JsCompiler; use crate::compilers::JsonCompiler; use crate::compilers::TsCompiler; use crate::deno_dir; +use crate::deno_error::permission_denied; use crate::file_fetcher::SourceFileFetcher; use crate::flags; use crate::global_timer::GlobalTimer; @@ -119,6 +120,7 @@ impl Loader for ThreadSafeState { specifier: &str, referrer: &str, is_main: bool, + is_dyn_import: bool, ) -> Result<ModuleSpecifier, ErrBox> { if !is_main { if let Some(import_map) = &self.import_map { @@ -128,8 +130,14 @@ impl Loader for ThreadSafeState { } } } + let module_specifier = + ModuleSpecifier::resolve_import(specifier, referrer)?; - ModuleSpecifier::resolve_import(specifier, referrer).map_err(ErrBox::from) + if is_dyn_import { + self.check_dyn_import(&module_specifier)?; + } + + Ok(module_specifier) } /// Given an absolute url, load its source code. @@ -294,7 +302,7 @@ impl ThreadSafeState { } #[inline] - pub fn check_net_url(&self, url: url::Url) -> Result<(), ErrBox> { + pub fn check_net_url(&self, url: &url::Url) -> Result<(), ErrBox> { self.permissions.check_net_url(url) } @@ -303,6 +311,30 @@ impl ThreadSafeState { self.permissions.check_run() } + pub fn check_dyn_import( + self: &Self, + module_specifier: &ModuleSpecifier, + ) -> Result<(), ErrBox> { + let u = module_specifier.as_url(); + match u.scheme() { + "http" | "https" => { + self.check_net_url(u)?; + Ok(()) + } + "file" => { + let filename = u + .to_file_path() + .unwrap() + .into_os_string() + .into_string() + .unwrap(); + self.check_read(&filename)?; + Ok(()) + } + _ => Err(permission_denied()), + } + } + #[cfg(test)] pub fn mock(argv: Vec<String>) -> ThreadSafeState { ThreadSafeState::new( |