From f200a330f70e514dd58a0dda98f33e747bed556a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Sat, 2 May 2020 13:37:48 +0200 Subject: [PATCH] BREAKING: disallow static import of local modules from remote modules This commit changes module loading logic to disallow statically import local module (file:// scheme) from remote modules (http://, https:// schemes). --- cli/ops/compiler.rs | 18 ++++++++++++++++++ cli/state.rs | 18 ++++++++++++++++++ .../error_local_static_import_from_remote.js | 1 + ...rror_local_static_import_from_remote.js.out | 2 ++ .../error_local_static_import_from_remote.ts | 1 + ...rror_local_static_import_from_remote.ts.out | 9 +++++++++ cli/tests/integration_tests.rs | 16 ++++++++++++++++ 7 files changed, 65 insertions(+) create mode 100644 cli/tests/error_local_static_import_from_remote.js create mode 100644 cli/tests/error_local_static_import_from_remote.js.out create mode 100644 cli/tests/error_local_static_import_from_remote.ts create mode 100644 cli/tests/error_local_static_import_from_remote.ts.out diff --git a/cli/ops/compiler.rs b/cli/ops/compiler.rs index 1029070a87fa48..c66b56d43cfeb1 100644 --- a/cli/ops/compiler.rs +++ b/cli/ops/compiler.rs @@ -112,6 +112,24 @@ fn op_fetch_source_files( async move { let resolved_specifier = ModuleSpecifier::resolve_url(&specifier) .expect("Invalid specifier"); + // TODO(bartlomieju): duplicated from `state.rs::ModuleLoader::load` - deduplicate + // Verify that remote file doesn't try to statically import local file. + if let Some(referrer) = ref_specifier_.as_ref() { + let referrer_url = referrer.as_url(); + match referrer_url.scheme() { + "http" | "https" => { + let specifier_url = resolved_specifier.as_url(); + match specifier_url.scheme() { + "http" | "https" => {}, + _ => { + let e = OpError::permission_denied("Remote module are not allowed to statically import local modules. Use dynamic import instead.".to_string()); + return Err(e.into()); + } + } + }, + _ => {} + } + } file_fetcher_ .fetch_source_file(&resolved_specifier, ref_specifier_) .await diff --git a/cli/state.rs b/cli/state.rs index 8003ea732f9862..6cc91573866f8d 100644 --- a/cli/state.rs +++ b/cli/state.rs @@ -287,6 +287,24 @@ impl ModuleLoader for State { if let Err(e) = self.check_dyn_import(&module_specifier) { return async move { Err(e.into()) }.boxed_local(); } + } else { + // Verify that remote file doesn't try to statically import local file. + if let Some(referrer) = maybe_referrer.as_ref() { + let referrer_url = referrer.as_url(); + match referrer_url.scheme() { + "http" | "https" => { + let specifier_url = module_specifier.as_url(); + match specifier_url.scheme() { + "http" | "https" => {} + _ => { + let e = OpError::permission_denied("Remote module are not allowed to statically import local modules. Use dynamic import instead.".to_string()); + return async move { Err(e.into()) }.boxed_local(); + } + } + } + _ => {} + } + } } let mut state = self.borrow_mut(); diff --git a/cli/tests/error_local_static_import_from_remote.js b/cli/tests/error_local_static_import_from_remote.js new file mode 100644 index 00000000000000..eb7fd23ba34f60 --- /dev/null +++ b/cli/tests/error_local_static_import_from_remote.js @@ -0,0 +1 @@ +import "file:///some/dir/file.js"; diff --git a/cli/tests/error_local_static_import_from_remote.js.out b/cli/tests/error_local_static_import_from_remote.js.out new file mode 100644 index 00000000000000..99e4b94c752795 --- /dev/null +++ b/cli/tests/error_local_static_import_from_remote.js.out @@ -0,0 +1,2 @@ +[WILDCARD] +Remote module are not allowed to statically import local modules. Use dynamic import instead. diff --git a/cli/tests/error_local_static_import_from_remote.ts b/cli/tests/error_local_static_import_from_remote.ts new file mode 100644 index 00000000000000..a831db0c449f37 --- /dev/null +++ b/cli/tests/error_local_static_import_from_remote.ts @@ -0,0 +1 @@ +import "file:///some/dir/file.ts"; diff --git a/cli/tests/error_local_static_import_from_remote.ts.out b/cli/tests/error_local_static_import_from_remote.ts.out new file mode 100644 index 00000000000000..de20b9d81111bc --- /dev/null +++ b/cli/tests/error_local_static_import_from_remote.ts.out @@ -0,0 +1,9 @@ +[WILDCARD] +error: Uncaught PermissionDenied: Remote module are not allowed to statically import local modules. Use dynamic import instead. + at unwrapResponse ($deno$/ops/dispatch_json.ts:[WILDCARD]) + at Object.sendAsync ($deno$/ops/dispatch_json.ts:[WILDCARD]) + at async processImports ($deno$/compiler/imports.ts:[WILDCARD]) + at async Object.processImports ($deno$/compiler/imports.ts:[WILDCARD]) + at async compile ([WILDCARD]compiler.ts:[WILDCARD]) + at async tsCompilerOnMessage ([WILDCARD]compiler.ts:[WILDCARD]) + at async workerMessageRecvCallback ($deno$/runtime_worker.ts:[WILDCARD]) diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index fbaab76747f1f8..7827d386a166fe 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -1422,6 +1422,22 @@ itest!(error_type_definitions { output: "error_type_definitions.ts.out", }); +itest!(error_local_static_import_from_remote_ts { + args: "run --reload http://localhost:4545/cli/tests/error_local_static_import_from_remote.ts", + check_stderr: true, + exit_code: 1, + http_server: true, + output: "error_local_static_import_from_remote.ts.out", +}); + +itest!(error_local_static_import_from_remote_js { + args: "run --reload http://localhost:4545/cli/tests/error_local_static_import_from_remote.js", + check_stderr: true, + exit_code: 1, + http_server: true, + output: "error_local_static_import_from_remote.js.out", +}); + // TODO(bartlomieju) Re-enable itest_ignore!(error_worker_dynamic { args: "run --reload error_worker_dynamic.ts",