summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/file_fetcher.rs11
-rw-r--r--cli/flags.rs89
-rw-r--r--cli/http_util.rs9
-rw-r--r--cli/lsp/registries.rs2
-rw-r--r--cli/main.rs8
-rw-r--r--cli/program_state.rs17
-rw-r--r--cli/specifier_handler.rs1
-rw-r--r--cli/standalone.rs3
-rw-r--r--cli/tests/cafile_ts_fetch_unsafe_ssl.ts.out2
-rw-r--r--cli/tests/cafile_url_imports_unsafe_ssl.ts.out3
-rw-r--r--cli/tests/integration/mod.rs13
-rw-r--r--cli/tools/standalone.rs5
-rw-r--r--extensions/fetch/lib.rs7
-rw-r--r--extensions/net/lib.rs10
-rw-r--r--extensions/net/ops_tls.rs17
-rw-r--r--extensions/tls/Cargo.toml2
-rw-r--r--extensions/tls/lib.rs59
-rw-r--r--extensions/websocket/lib.rs21
-rw-r--r--runtime/build.rs7
-rw-r--r--runtime/examples/hello_runtime.rs1
-rw-r--r--runtime/web_worker.rs4
-rw-r--r--runtime/worker.rs5
22 files changed, 284 insertions, 12 deletions
diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs
index 207f08c64..e61c3beb9 100644
--- a/cli/file_fetcher.rs
+++ b/cli/file_fetcher.rs
@@ -223,6 +223,7 @@ impl FileFetcher {
allow_remote: bool,
root_cert_store: Option<RootCertStore>,
blob_store: BlobStore,
+ unsafely_treat_insecure_origin_as_secure: Option<Vec<String>>,
) -> Result<Self, AnyError> {
Ok(Self {
auth_tokens: AuthTokens::new(env::var(DENO_AUTH_TOKENS).ok()),
@@ -235,6 +236,7 @@ impl FileFetcher {
root_cert_store,
None,
None,
+ unsafely_treat_insecure_origin_as_secure,
)?,
blob_store,
})
@@ -618,6 +620,7 @@ mod tests {
true,
None,
blob_store.clone(),
+ None,
)
.expect("setup failed");
(file_fetcher, temp_dir, blob_store)
@@ -1063,6 +1066,7 @@ mod tests {
true,
None,
BlobStore::default(),
+ None,
)
.expect("setup failed");
let result = file_fetcher
@@ -1090,6 +1094,7 @@ mod tests {
true,
None,
BlobStore::default(),
+ None,
)
.expect("could not create file fetcher");
let specifier =
@@ -1118,6 +1123,7 @@ mod tests {
true,
None,
BlobStore::default(),
+ None,
)
.expect("could not create file fetcher");
let result = file_fetcher_02
@@ -1279,6 +1285,7 @@ mod tests {
true,
None,
BlobStore::default(),
+ None,
)
.expect("could not create file fetcher");
let specifier =
@@ -1310,6 +1317,7 @@ mod tests {
true,
None,
BlobStore::default(),
+ None,
)
.expect("could not create file fetcher");
let result = file_fetcher_02
@@ -1420,6 +1428,7 @@ mod tests {
false,
None,
BlobStore::default(),
+ None,
)
.expect("could not create file fetcher");
let specifier =
@@ -1447,6 +1456,7 @@ mod tests {
true,
None,
BlobStore::default(),
+ None,
)
.expect("could not create file fetcher");
let file_fetcher_02 = FileFetcher::new(
@@ -1455,6 +1465,7 @@ mod tests {
true,
None,
BlobStore::default(),
+ None,
)
.expect("could not create file fetcher");
let specifier =
diff --git a/cli/flags.rs b/cli/flags.rs
index 1c7eaf9a0..36b326c0b 100644
--- a/cli/flags.rs
+++ b/cli/flags.rs
@@ -164,6 +164,7 @@ pub struct Flags {
pub repl: bool,
pub seed: Option<u64>,
pub unstable: bool,
+ pub unsafely_treat_insecure_origin_as_secure: Option<Vec<String>>,
pub v8_flags: Vec<String>,
pub version: bool,
pub watch: bool,
@@ -216,6 +217,20 @@ impl Flags {
_ => {}
}
+ match &self.unsafely_treat_insecure_origin_as_secure {
+ Some(ic_allowlist) if ic_allowlist.is_empty() => {
+ args.push("--unsafely-treat-insecure-origin-as-secure".to_string());
+ }
+ Some(ic_allowlist) => {
+ let s = format!(
+ "--unsafely-treat-insecure-origin-as-secure={}",
+ ic_allowlist.join(",")
+ );
+ args.push(s);
+ }
+ _ => {}
+ }
+
match &self.allow_env {
Some(env_allowlist) if env_allowlist.is_empty() => {
args.push("--allow-env".to_string());
@@ -1222,6 +1237,16 @@ fn permission_args<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
.validator(crate::flags_allow_net::validator),
)
.arg(
+ Arg::with_name("unsafely-treat-insecure-origin-as-secure")
+ .long("unsafely-treat-insecure-origin-as-secure")
+ .min_values(0)
+ .takes_value(true)
+ .use_delimiter(true)
+ .require_equals(true)
+ .help("DANGER: Disables verification of SSL certificates")
+ .validator(crate::flags_allow_net::validator),
+ )
+ .arg(
Arg::with_name("allow-env")
.long("allow-env")
.min_values(0)
@@ -1879,7 +1904,15 @@ fn permission_args_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
crate::flags_allow_net::parse(net_wl.map(ToString::to_string).collect())
.unwrap();
flags.allow_net = Some(net_allowlist);
- debug!("net allowlist: {:#?}", &flags.allow_net);
+ }
+
+ if let Some(ic_wl) =
+ matches.values_of("unsafely-treat-insecure-origin-as-secure")
+ {
+ let ic_allowlist: Vec<String> =
+ crate::flags_allow_net::parse(ic_wl.map(ToString::to_string).collect())
+ .unwrap();
+ flags.unsafely_treat_insecure_origin_as_secure = Some(ic_allowlist);
}
if let Some(env_wl) = matches.values_of("allow-env") {
@@ -2723,6 +2756,7 @@ mod tests {
repl: true,
subcommand: DenoSubcommand::Repl { eval: None },
allow_net: Some(vec![]),
+ unsafely_treat_insecure_origin_as_secure: None,
allow_env: Some(vec![]),
allow_run: Some(vec![]),
allow_read: Some(vec![]),
@@ -3198,7 +3232,7 @@ mod tests {
#[test]
fn install_with_flags() {
#[rustfmt::skip]
- let r = flags_from_vec(svec!["deno", "install", "--import-map", "import_map.json", "--no-remote", "--config", "tsconfig.json", "--no-check", "--reload", "--lock", "lock.json", "--lock-write", "--cert", "example.crt", "--cached-only", "--allow-read", "--allow-net", "--v8-flags=--help", "--seed", "1", "--inspect=127.0.0.1:9229", "--name", "file_server", "--root", "/foo", "--force", "https://deno.land/std/http/file_server.ts", "foo", "bar"]);
+ let r = flags_from_vec(svec!["deno", "install", "--import-map", "import_map.json", "--no-remote", "--config", "tsconfig.json", "--no-check", "--unsafely-treat-insecure-origin-as-secure", "--reload", "--lock", "lock.json", "--lock-write", "--cert", "example.crt", "--cached-only", "--allow-read", "--allow-net", "--v8-flags=--help", "--seed", "1", "--inspect=127.0.0.1:9229", "--name", "file_server", "--root", "/foo", "--force", "https://deno.land/std/http/file_server.ts", "foo", "bar"]);
assert_eq!(
r.unwrap(),
Flags {
@@ -3222,6 +3256,7 @@ mod tests {
seed: Some(1),
inspect: Some("127.0.0.1:9229".parse().unwrap()),
allow_net: Some(vec![]),
+ unsafely_treat_insecure_origin_as_secure: Some(vec![]),
allow_read: Some(vec![]),
..Flags::default()
}
@@ -3367,6 +3402,53 @@ mod tests {
}
#[test]
+ fn unsafely_treat_insecure_origin_as_secure() {
+ let r = flags_from_vec(svec![
+ "deno",
+ "run",
+ "--unsafely-treat-insecure-origin-as-secure",
+ "script.ts"
+ ]);
+ assert_eq!(
+ r.unwrap(),
+ Flags {
+ subcommand: DenoSubcommand::Run {
+ script: "script.ts".to_string(),
+ },
+ unsafely_treat_insecure_origin_as_secure: Some(vec![]),
+ ..Flags::default()
+ }
+ );
+ }
+
+ #[test]
+ fn unsafely_treat_insecure_origin_as_secure_with_ipv6_address() {
+ let r = flags_from_vec(svec![
+ "deno",
+ "run",
+ "--unsafely-treat-insecure-origin-as-secure=deno.land,localhost,::,127.0.0.1,[::1],1.2.3.4",
+ "script.ts"
+ ]);
+ assert_eq!(
+ r.unwrap(),
+ Flags {
+ subcommand: DenoSubcommand::Run {
+ script: "script.ts".to_string(),
+ },
+ unsafely_treat_insecure_origin_as_secure: Some(svec![
+ "deno.land",
+ "localhost",
+ "::",
+ "127.0.0.1",
+ "[::1]",
+ "1.2.3.4"
+ ]),
+ ..Flags::default()
+ }
+ );
+ }
+
+ #[test]
fn no_remote() {
let r = flags_from_vec(svec!["deno", "run", "--no-remote", "script.ts"]);
assert_eq!(
@@ -3845,7 +3927,7 @@ mod tests {
#[test]
fn compile_with_flags() {
#[rustfmt::skip]
- let r = flags_from_vec(svec!["deno", "compile", "--import-map", "import_map.json", "--no-remote", "--config", "tsconfig.json", "--no-check", "--reload", "--lock", "lock.json", "--lock-write", "--cert", "example.crt", "--cached-only", "--location", "https:foo", "--allow-read", "--allow-net", "--v8-flags=--help", "--seed", "1", "--output", "colors", "https://deno.land/std/examples/colors.ts", "foo", "bar"]);
+ let r = flags_from_vec(svec!["deno", "compile", "--import-map", "import_map.json", "--no-remote", "--config", "tsconfig.json", "--no-check", "--unsafely-treat-insecure-origin-as-secure", "--reload", "--lock", "lock.json", "--lock-write", "--cert", "example.crt", "--cached-only", "--location", "https:foo", "--allow-read", "--allow-net", "--v8-flags=--help", "--seed", "1", "--output", "colors", "https://deno.land/std/examples/colors.ts", "foo", "bar"]);
assert_eq!(
r.unwrap(),
Flags {
@@ -3866,6 +3948,7 @@ mod tests {
cached_only: true,
location: Some(Url::parse("https://foo/").unwrap()),
allow_read: Some(vec![]),
+ unsafely_treat_insecure_origin_as_secure: Some(vec![]),
allow_net: Some(vec![]),
v8_flags: svec!["--help", "--random-seed=1"],
seed: Some(1),
diff --git a/cli/http_util.rs b/cli/http_util.rs
index 671093923..ac8e1dff6 100644
--- a/cli/http_util.rs
+++ b/cli/http_util.rs
@@ -145,7 +145,8 @@ mod tests {
use std::fs::read;
fn create_test_client(ca_data: Option<Vec<u8>>) -> Client {
- create_http_client("test_client".to_string(), None, ca_data, None).unwrap()
+ create_http_client("test_client".to_string(), None, ca_data, None, None)
+ .unwrap()
}
#[tokio::test]
@@ -347,6 +348,7 @@ mod tests {
.unwrap(),
),
None,
+ None,
)
.unwrap();
let result = fetch_once(FetchOnceArgs {
@@ -376,6 +378,7 @@ mod tests {
None, // This will load mozilla certs by default
None,
None,
+ None,
)
.unwrap();
@@ -407,6 +410,7 @@ mod tests {
Some(RootCertStore::empty()), // no certs loaded at all
None,
None,
+ None,
)
.unwrap();
@@ -445,6 +449,7 @@ mod tests {
.unwrap(),
),
None,
+ None,
)
.unwrap();
let result = fetch_once(FetchOnceArgs {
@@ -484,6 +489,7 @@ mod tests {
.unwrap(),
),
None,
+ None,
)
.unwrap();
let result = fetch_once(FetchOnceArgs {
@@ -537,6 +543,7 @@ mod tests {
.unwrap(),
),
None,
+ None,
)
.unwrap();
let result = fetch_once(FetchOnceArgs {
diff --git a/cli/lsp/registries.rs b/cli/lsp/registries.rs
index 6a1dc1a4b..1bf140019 100644
--- a/cli/lsp/registries.rs
+++ b/cli/lsp/registries.rs
@@ -266,6 +266,7 @@ impl Default for ModuleRegistry {
true,
None,
BlobStore::default(),
+ None,
)
.unwrap();
@@ -285,6 +286,7 @@ impl ModuleRegistry {
true,
None,
BlobStore::default(),
+ None,
)
.context("Error creating file fetcher in module registry.")
.unwrap();
diff --git a/cli/main.rs b/cli/main.rs
index 77cce1d05..93b3d5021 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -109,6 +109,10 @@ fn create_web_worker_callback(
.log_level
.map_or(false, |l| l == log::Level::Debug),
unstable: program_state.flags.unstable,
+ unsafely_treat_insecure_origin_as_secure: program_state
+ .flags
+ .unsafely_treat_insecure_origin_as_secure
+ .clone(),
root_cert_store: program_state.root_cert_store.clone(),
user_agent: version::get_user_agent(),
seed: program_state.flags.seed,
@@ -189,6 +193,10 @@ pub fn create_main_worker(
.log_level
.map_or(false, |l| l == log::Level::Debug),
unstable: program_state.flags.unstable,
+ unsafely_treat_insecure_origin_as_secure: program_state
+ .flags
+ .unsafely_treat_insecure_origin_as_secure
+ .clone(),
root_cert_store: program_state.root_cert_store.clone(),
user_agent: version::get_user_agent(),
seed: program_state.flags.seed,
diff --git a/cli/program_state.rs b/cli/program_state.rs
index 244351a03..721ccda9c 100644
--- a/cli/program_state.rs
+++ b/cli/program_state.rs
@@ -1,5 +1,6 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+use crate::colors;
use crate::config_file::ConfigFile;
use crate::deno_dir;
use crate::file_fetcher::CacheSetting;
@@ -117,6 +118,21 @@ impl ProgramState {
}
}
+ if let Some(insecure_allowlist) =
+ flags.unsafely_treat_insecure_origin_as_secure.as_ref()
+ {
+ let domains = if insecure_allowlist.is_empty() {
+ "for all domains".to_string()
+ } else {
+ format!("for: {}", insecure_allowlist.join(", "))
+ };
+ let msg = format!(
+ "DANGER: SSL ceritificate validation is disabled {}",
+ domains
+ );
+ eprintln!("{}", colors::yellow(msg));
+ }
+
let cache_usage = if flags.cached_only {
CacheSetting::Only
} else if !flags.cache_blocklist.is_empty() {
@@ -137,6 +153,7 @@ impl ProgramState {
!flags.no_remote,
Some(root_cert_store.clone()),
blob_store.clone(),
+ flags.unsafely_treat_insecure_origin_as_secure.clone(),
)?;
let lockfile = if let Some(filename) = &flags.lock {
diff --git a/cli/specifier_handler.rs b/cli/specifier_handler.rs
index 5fd9d6b25..ddc3adc7e 100644
--- a/cli/specifier_handler.rs
+++ b/cli/specifier_handler.rs
@@ -598,6 +598,7 @@ pub mod tests {
true,
None,
BlobStore::default(),
+ None,
)
.expect("could not setup");
let disk_cache = deno_dir.gen_cache;
diff --git a/cli/standalone.rs b/cli/standalone.rs
index 460ee23d0..ded3c88e8 100644
--- a/cli/standalone.rs
+++ b/cli/standalone.rs
@@ -57,6 +57,7 @@ pub struct Metadata {
pub log_level: Option<Level>,
pub ca_stores: Option<Vec<String>>,
pub ca_data: Option<Vec<u8>>,
+ pub unsafely_treat_insecure_origin_as_secure: Option<Vec<String>>,
}
pub const MAGIC_TRAILER: &[u8; 8] = b"d3n0l4nd";
@@ -252,6 +253,8 @@ pub async fn run(
debug_flag: metadata.log_level.map_or(false, |l| l == log::Level::Debug),
user_agent: version::get_user_agent(),
unstable: metadata.unstable,
+ unsafely_treat_insecure_origin_as_secure: metadata
+ .unsafely_treat_insecure_origin_as_secure,
root_cert_store: Some(root_cert_store),
seed: metadata.seed,
js_error_create_fn: None,
diff --git a/cli/tests/cafile_ts_fetch_unsafe_ssl.ts.out b/cli/tests/cafile_ts_fetch_unsafe_ssl.ts.out
new file mode 100644
index 000000000..f0b63833a
--- /dev/null
+++ b/cli/tests/cafile_ts_fetch_unsafe_ssl.ts.out
@@ -0,0 +1,2 @@
+DANGER: SSL ceritificate validation is disabled for all domains
+Hello
diff --git a/cli/tests/cafile_url_imports_unsafe_ssl.ts.out b/cli/tests/cafile_url_imports_unsafe_ssl.ts.out
new file mode 100644
index 000000000..3f6a0c07f
--- /dev/null
+++ b/cli/tests/cafile_url_imports_unsafe_ssl.ts.out
@@ -0,0 +1,3 @@
+DANGER: SSL ceritificate validation is disabled for: localhost
+Hello
+success
diff --git a/cli/tests/integration/mod.rs b/cli/tests/integration/mod.rs
index cc016382f..938d40125 100644
--- a/cli/tests/integration/mod.rs
+++ b/cli/tests/integration/mod.rs
@@ -474,6 +474,19 @@ fn broken_stdout() {
// http_server: true,
// });
+itest!(cafile_url_imports_unsafe_ssl {
+ args: "run --quiet --reload --unsafely-treat-insecure-origin-as-secure=localhost cafile_url_imports.ts",
+ output: "cafile_url_imports_unsafe_ssl.ts.out",
+ http_server: true,
+});
+
+itest!(cafile_ts_fetch_unsafe_ssl {
+ args:
+ "run --quiet --reload --allow-net --unsafely-treat-insecure-origin-as-secure cafile_ts_fetch.ts",
+ output: "cafile_ts_fetch_unsafe_ssl.ts.out",
+ http_server: true,
+});
+
#[test]
#[ignore]
fn cafile_env_fetch() {
diff --git a/cli/tools/standalone.rs b/cli/tools/standalone.rs
index 46ac27b83..2eaf50161 100644
--- a/cli/tools/standalone.rs
+++ b/cli/tools/standalone.rs
@@ -99,6 +99,9 @@ pub fn create_standalone_binary(
location: flags.location.clone(),
permissions: flags.clone().into(),
v8_flags: flags.v8_flags.clone(),
+ unsafely_treat_insecure_origin_as_secure: flags
+ .unsafely_treat_insecure_origin_as_secure
+ .clone(),
log_level: flags.log_level,
ca_stores: flags.ca_stores,
ca_data,
@@ -223,6 +226,8 @@ pub fn compile_to_runtime_flags(
lock: None,
log_level: flags.log_level,
no_check: false,
+ unsafely_treat_insecure_origin_as_secure: flags
+ .unsafely_treat_insecure_origin_as_secure,
no_remote: false,
prompt: flags.prompt,
reload: false,
diff --git a/extensions/fetch/lib.rs b/extensions/fetch/lib.rs
index 0ac853cbc..cc5954b74 100644
--- a/extensions/fetch/lib.rs
+++ b/extensions/fetch/lib.rs
@@ -60,6 +60,7 @@ pub fn init<P: FetchPermissions + 'static>(
root_cert_store: Option<RootCertStore>,
proxy: Option<Proxy>,
request_builder_hook: Option<fn(RequestBuilder) -> RequestBuilder>,
+ unsafely_treat_insecure_origin_as_secure: Option<Vec<String>>,
) -> Extension {
Extension::builder()
.js(include_js_files!(
@@ -87,6 +88,7 @@ pub fn init<P: FetchPermissions + 'static>(
root_cert_store.clone(),
None,
proxy.clone(),
+ unsafely_treat_insecure_origin_as_secure.clone(),
)
.unwrap()
});
@@ -95,6 +97,8 @@ pub fn init<P: FetchPermissions + 'static>(
root_cert_store: root_cert_store.clone(),
proxy: proxy.clone(),
request_builder_hook,
+ unsafely_treat_insecure_origin_as_secure:
+ unsafely_treat_insecure_origin_as_secure.clone(),
});
Ok(())
})
@@ -106,6 +110,7 @@ pub struct HttpClientDefaults {
pub root_cert_store: Option<RootCertStore>,
pub proxy: Option<Proxy>,
pub request_builder_hook: Option<fn(RequestBuilder) -> RequestBuilder>,
+ pub unsafely_treat_insecure_origin_as_secure: Option<Vec<String>>,
}
pub trait FetchPermissions {
@@ -532,11 +537,13 @@ where
let defaults = state.borrow::<HttpClientDefaults>();
let cert_data =
get_cert_data(args.ca_file.as_deref(), args.ca_data.as_deref())?;
+
let client = create_http_client(
defaults.user_agent.clone(),
defaults.root_cert_store.clone(),
cert_data,
args.proxy,
+ defaults.unsafely_treat_insecure_origin_as_secure.clone(),
)
.unwrap();
diff --git a/extensions/net/lib.rs b/extensions/net/lib.rs
index 6b0b728b1..f68034517 100644
--- a/extensions/net/lib.rs
+++ b/extensions/net/lib.rs
@@ -94,9 +94,16 @@ pub struct DefaultTlsOptions {
pub root_cert_store: Option<RootCertStore>,
}
+/// `UnsafelyTreatInsecureOriginAsSecure` is a wrapper struct so it can be placed inside `GothamState`;
+/// using type alias for a `Option<Vec<String>>` could work, but there's a high chance
+/// that there might be another type alias pointing to a `Option<Vec<String>>`, which
+/// would override previously used alias.
+pub struct UnsafelyTreatInsecureOriginAsSecure(Option<Vec<String>>);
+
pub fn init<P: NetPermissions + 'static>(
root_cert_store: Option<RootCertStore>,
unstable: bool,
+ unsafely_treat_insecure_origin_as_secure: Option<Vec<String>>,
) -> Extension {
let mut ops_to_register = vec![];
ops_to_register.extend(io::init());
@@ -115,6 +122,9 @@ pub fn init<P: NetPermissions + 'static>(
root_cert_store: root_cert_store.clone(),
});
state.put(UnstableChecker { unstable });
+ state.put(UnsafelyTreatInsecureOriginAsSecure(
+ unsafely_treat_insecure_origin_as_secure.clone(),
+ ));
Ok(())
})
.build()
diff --git a/extensions/net/ops_tls.rs b/extensions/net/ops_tls.rs
index 7c4563390..6c26ed748 100644
--- a/extensions/net/ops_tls.rs
+++ b/extensions/net/ops_tls.rs
@@ -9,6 +9,7 @@ use crate::resolve_addr::resolve_addr;
use crate::resolve_addr::resolve_addr_sync;
use crate::DefaultTlsOptions;
use crate::NetPermissions;
+use crate::UnsafelyTreatInsecureOriginAsSecure;
use deno_core::error::bad_resource;
use deno_core::error::bad_resource_id;
use deno_core::error::custom_error;
@@ -720,8 +721,8 @@ where
let local_addr = tcp_stream.local_addr()?;
let remote_addr = tcp_stream.peer_addr()?;
- let tls_config = Arc::new(create_client_config(root_cert_store, ca_data)?);
-
+ let tls_config =
+ Arc::new(create_client_config(root_cert_store, ca_data, None)?);
let tls_stream =
TlsStream::new_client_side(tcp_stream, &tls_config, hostname_dns);
@@ -760,6 +761,11 @@ where
};
let port = args.port;
let cert_file = args.cert_file.as_deref();
+ let unsafely_treat_insecure_origin_as_secure = state
+ .borrow()
+ .borrow::<UnsafelyTreatInsecureOriginAsSecure>()
+ .0
+ .clone();
if args.cert_chain.is_some() {
super::check_unstable2(&state, "ConnectTlsOptions.certChain");
@@ -801,8 +807,11 @@ where
let tcp_stream = TcpStream::connect(connect_addr).await?;
let local_addr = tcp_stream.local_addr()?;
let remote_addr = tcp_stream.peer_addr()?;
-
- let mut tls_config = create_client_config(root_cert_store, ca_data)?;
+ let mut tls_config = create_client_config(
+ root_cert_store,
+ ca_data,
+ unsafely_treat_insecure_origin_as_secure,
+ )?;
if args.cert_chain.is_some() || args.private_key.is_some() {
let cert_chain = args
diff --git a/extensions/tls/Cargo.toml b/extensions/tls/Cargo.toml
index ee7be04dc..e75d0bbfe 100644
--- a/extensions/tls/Cargo.toml
+++ b/extensions/tls/Cargo.toml
@@ -17,7 +17,7 @@ path = "lib.rs"
deno_core = { version = "0.95.0", path = "../../core" }
lazy_static = "1.4.0"
reqwest = { version = "0.11.4", default-features = false, features = ["rustls-tls", "stream", "gzip", "brotli"] }
-rustls = "0.19.0"
+rustls = { version = "0.19.1", features = ["dangerous_configuration"] }
rustls-native-certs = "0.5.0"
serde = { version = "1.0.126", features = ["derive"] }
webpki = "0.21.4"
diff --git a/extensions/tls/lib.rs b/extensions/tls/lib.rs
index f91249792..2a15b4e75 100644
--- a/extensions/tls/lib.rs
+++ b/extensions/tls/lib.rs
@@ -16,20 +16,65 @@ use reqwest::header::HeaderMap;
use reqwest::header::USER_AGENT;
use reqwest::redirect::Policy;
use reqwest::Client;
+use rustls::internal::msgs::handshake::DigitallySignedStruct;
+use rustls::Certificate;
use rustls::ClientConfig;
+use rustls::HandshakeSignatureValid;
use rustls::RootCertStore;
+use rustls::ServerCertVerified;
+use rustls::ServerCertVerifier;
use rustls::StoresClientSessions;
+use rustls::TLSError;
use serde::Deserialize;
use std::collections::HashMap;
use std::io::BufReader;
use std::io::Cursor;
use std::sync::Arc;
+use webpki::DNSNameRef;
/// This extension has no runtime apis, it only exports some shared native functions.
pub fn init() -> Extension {
Extension::builder().build()
}
+pub struct NoCertificateVerification(pub Vec<String>);
+
+impl ServerCertVerifier for NoCertificateVerification {
+ fn verify_server_cert(
+ &self,
+ _roots: &RootCertStore,
+ _presented_certs: &[Certificate],
+ dns_name: DNSNameRef<'_>,
+ _ocsp: &[u8],
+ ) -> Result<ServerCertVerified, TLSError> {
+ let dns_name: &str = dns_name.into();
+ let dns_name: String = dns_name.to_owned();
+ if self.0.is_empty() || self.0.contains(&dns_name) {
+ Ok(ServerCertVerified::assertion())
+ } else {
+ Err(TLSError::General(dns_name))
+ }
+ }
+
+ fn verify_tls12_signature(
+ &self,
+ _message: &[u8],
+ _cert: &Certificate,
+ _dss: &DigitallySignedStruct,
+ ) -> Result<HandshakeSignatureValid, TLSError> {
+ Ok(HandshakeSignatureValid::assertion())
+ }
+
+ fn verify_tls13_signature(
+ &self,
+ _message: &[u8],
+ _cert: &Certificate,
+ _dss: &DigitallySignedStruct,
+ ) -> Result<HandshakeSignatureValid, TLSError> {
+ Ok(HandshakeSignatureValid::assertion())
+ }
+}
+
#[derive(Deserialize, Default, Debug, Clone)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
@@ -80,6 +125,7 @@ pub fn create_default_root_cert_store() -> RootCertStore {
pub fn create_client_config(
root_cert_store: Option<RootCertStore>,
ca_data: Option<Vec<u8>>,
+ unsafely_treat_insecure_origin_as_secure: Option<Vec<String>>,
) -> Result<ClientConfig, AnyError> {
let mut tls_config = ClientConfig::new();
tls_config.set_persistence(CLIENT_SESSION_MEMORY_CACHE.clone());
@@ -95,6 +141,12 @@ pub fn create_client_config(
}
}
+ if let Some(ic_allowlist) = unsafely_treat_insecure_origin_as_secure {
+ tls_config.dangerous().set_certificate_verifier(Arc::new(
+ NoCertificateVerification(ic_allowlist),
+ ));
+ }
+
Ok(tls_config)
}
@@ -105,8 +157,13 @@ pub fn create_http_client(
root_cert_store: Option<RootCertStore>,
ca_data: Option<Vec<u8>>,
proxy: Option<Proxy>,
+ unsafely_treat_insecure_origin_as_secure: Option<Vec<String>>,
) -> Result<Client, AnyError> {
- let tls_config = create_client_config(root_cert_store, ca_data)?;
+ let tls_config = create_client_config(
+ root_cert_store,
+ ca_data,
+ unsafely_treat_insecure_origin_as_secure,
+ )?;
let mut headers = HeaderMap::new();
headers.insert(USER_AGENT, user_agent.parse().unwrap());
let mut builder = Client::builder()
diff --git a/extensions/websocket/lib.rs b/extensions/websocket/lib.rs
index 01f0a523d..896a5f2e2 100644
--- a/extensions/websocket/lib.rs
+++ b/extensions/websocket/lib.rs
@@ -54,6 +54,12 @@ pub trait WebSocketPermissions {
fn check_net_url(&mut self, _url: &url::Url) -> Result<(), AnyError>;
}
+/// `UnsafelyTreatInsecureOriginAsSecure` is a wrapper struct so it can be placed inside `GothamState`;
+/// using type alias for a `Option<Vec<String>>` could work, but there's a high chance
+/// that there might be another type alias pointing to a `Option<Vec<String>>`, which
+/// would override previously used alias.
+pub struct UnsafelyTreatInsecureOriginAsSecure(Option<Vec<String>>);
+
/// For use with `op_websocket_*` when the user does not want permissions.
pub struct NoWebSocketPermissions;
@@ -197,6 +203,11 @@ where
);
}
+ let unsafely_treat_insecure_origin_as_secure = state
+ .borrow()
+ .borrow::<UnsafelyTreatInsecureOriginAsSecure>()
+ .0
+ .clone();
let root_cert_store = state.borrow().borrow::<WsRootStore>().0.clone();
let user_agent = state.borrow().borrow::<WsUserAgent>().0.clone();
let uri: Uri = args.url.parse()?;
@@ -221,7 +232,11 @@ where
let socket: MaybeTlsStream<TcpStream> = match uri.scheme_str() {
Some("ws") => MaybeTlsStream::Plain(tcp_socket),
Some("wss") => {
- let tls_config = create_client_config(root_cert_store, None)?;
+ let tls_config = create_client_config(
+ root_cert_store,
+ None,
+ unsafely_treat_insecure_origin_as_secure,
+ )?;
let tls_connector = TlsConnector::from(Arc::new(tls_config));
let dnsname = DNSNameRef::try_from_ascii_str(domain)
.map_err(|_| invalid_hostname(domain))?;
@@ -377,6 +392,7 @@ pub async fn op_ws_next_event(
pub fn init<P: WebSocketPermissions + 'static>(
user_agent: String,
root_cert_store: Option<RootCertStore>,
+ unsafely_treat_insecure_origin_as_secure: Option<Vec<String>>,
) -> Extension {
Extension::builder()
.js(include_js_files!(
@@ -395,6 +411,9 @@ pub fn init<P: WebSocketPermissions + 'static>(
])
.state(move |state| {
state.put::<WsUserAgent>(WsUserAgent(user_agent.clone()));
+ state.put(UnsafelyTreatInsecureOriginAsSecure(
+ unsafely_treat_insecure_origin_as_secure.clone(),
+ ));
state.put::<WsRootStore>(WsRootStore(root_cert_store.clone()));
Ok(())
})
diff --git a/runtime/build.rs b/runtime/build.rs
index e6f7de641..3003fb231 100644
--- a/runtime/build.rs
+++ b/runtime/build.rs
@@ -48,10 +48,12 @@ fn create_runtime_snapshot(snapshot_path: &Path, files: Vec<PathBuf>) {
None,
None,
None,
+ None,
),
deno_websocket::init::<deno_websocket::NoWebSocketPermissions>(
"".to_owned(),
None,
+ None,
),
deno_webstorage::init(None),
deno_crypto::init(None),
@@ -62,7 +64,10 @@ fn create_runtime_snapshot(snapshot_path: &Path, files: Vec<PathBuf>) {
false, // No --unstable.
),
deno_ffi::init::<deno_ffi::NoFfiPermissions>(false),
- deno_net::init::<deno_net::NoNetPermissions>(None, false), // No --unstable.
+ deno_net::init::<deno_net::NoNetPermissions>(
+ None, false, // No --unstable.
+ None,
+ ),
deno_http::init(),
];
diff --git a/runtime/examples/hello_runtime.rs b/runtime/examples/hello_runtime.rs
index eaedcac10..e3a8b88b2 100644
--- a/runtime/examples/hello_runtime.rs
+++ b/runtime/examples/hello_runtime.rs
@@ -27,6 +27,7 @@ async fn main() -> Result<(), AnyError> {
args: vec![],
debug_flag: false,
unstable: false,
+ unsafely_treat_insecure_origin_as_secure: None,
root_cert_store: None,
user_agent: "hello_runtime".to_string(),
seed: None,
diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs
index 3f68fc4e6..1349c510a 100644
--- a/runtime/web_worker.rs
+++ b/runtime/web_worker.rs
@@ -253,6 +253,7 @@ pub struct WebWorkerOptions {
pub args: Vec<String>,
pub debug_flag: bool,
pub unstable: bool,
+ pub unsafely_treat_insecure_origin_as_secure: Option<Vec<String>>,
pub root_cert_store: Option<RootCertStore>,
pub user_agent: String,
pub seed: Option<u64>,
@@ -304,10 +305,12 @@ impl WebWorker {
options.root_cert_store.clone(),
None,
None,
+ options.unsafely_treat_insecure_origin_as_secure.clone(),
),
deno_websocket::init::<Permissions>(
options.user_agent.clone(),
options.root_cert_store.clone(),
+ options.unsafely_treat_insecure_origin_as_secure.clone(),
),
deno_broadcast_channel::init(
options.broadcast_channel.clone(),
@@ -341,6 +344,7 @@ impl WebWorker {
deno_net::init::<Permissions>(
options.root_cert_store.clone(),
options.unstable,
+ options.unsafely_treat_insecure_origin_as_secure.clone(),
),
ops::os::init(),
ops::permissions::init(),
diff --git a/runtime/worker.rs b/runtime/worker.rs
index 69602d0dd..f8b0edb64 100644
--- a/runtime/worker.rs
+++ b/runtime/worker.rs
@@ -50,6 +50,7 @@ pub struct WorkerOptions {
pub args: Vec<String>,
pub debug_flag: bool,
pub unstable: bool,
+ pub unsafely_treat_insecure_origin_as_secure: Option<Vec<String>>,
pub root_cert_store: Option<RootCertStore>,
pub user_agent: String,
pub seed: Option<u64>,
@@ -103,10 +104,12 @@ impl MainWorker {
options.root_cert_store.clone(),
None,
None,
+ options.unsafely_treat_insecure_origin_as_secure.clone(),
),
deno_websocket::init::<Permissions>(
options.user_agent.clone(),
options.root_cert_store.clone(),
+ options.unsafely_treat_insecure_origin_as_secure.clone(),
),
deno_webstorage::init(options.origin_storage_dir.clone()),
deno_crypto::init(options.seed),
@@ -131,6 +134,7 @@ impl MainWorker {
deno_net::init::<Permissions>(
options.root_cert_store.clone(),
options.unstable,
+ options.unsafely_treat_insecure_origin_as_secure.clone(),
),
ops::os::init(),
ops::permissions::init(),
@@ -300,6 +304,7 @@ mod tests {
args: vec![],
debug_flag: false,
unstable: false,
+ unsafely_treat_insecure_origin_as_secure: None,
root_cert_store: None,
seed: None,
js_error_create_fn: None,