From be2e0ee6c25a9b6e987b158dc53f10291acbbc0c Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Tue, 21 Sep 2021 13:22:01 -0500 Subject: [PATCH 1/3] feat: adds options to bypass SSL validation --- Cargo.lock | 7 ++++++ Cargo.toml | 1 + docs/source/configuring.md | 8 +++++++ src/cli.rs | 48 ++++++++++++++++++++++++++++++++++---- src/utils/client.rs | 13 +++++++++++ 5 files changed, 73 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a8db2298d..0e64197ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1709,6 +1709,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "levenshtein" version = "1.0.5" @@ -2477,6 +2483,7 @@ dependencies = [ "harmonizer", "heck", "houston", + "lazycell", "opener", "os_info", "predicates", diff --git a/Cargo.toml b/Cargo.toml index d73544218..27f873c46 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,7 @@ git-url-parse = "0.3" git2 = { version = "0.13", default-features = false, features = ["vendored-openssl"] } harmonizer = { version = "0.27.0", optional = true } heck = "0.3" +lazycell = "1" opener = "0.5" os_info = "3.0" prettytable-rs = "0.8" diff --git a/docs/source/configuring.md b/docs/source/configuring.md index 7e72883b1..3abb13d86 100644 --- a/docs/source/configuring.md +++ b/docs/source/configuring.md @@ -265,6 +265,14 @@ If you use a version control system besides Git, you can use the environment var Currently, only Git is fully supported by Apollo Studio. +## Bypass SSL/TLS Validation + +Sometimes, you may want to perform HTTPS requests from Rover, but skip validation checks. This is generally not recommended and insecure, but there are two flags you can use to configure how Rover validates HTTPS requests. + +The `--insecure-accept-invalid-hostnames` flag will disable hostname validation. If hostname verification is not used, any valid certificate for any site will be trusted for use from any other. This introduces a significant vulnerability to man-in-the-middle attacks. + +The `--insecure-accept-invalid-certs` flag will disable certificate validation. If invalid certificates are trusted, any certificate for any site will be trusted for use. This includes expired certificates. This introduces significant vulnerabilities, and should only be used as a last resort. + ## Supported environment variables You can configure Rover's behavior by setting the environment variables listed below. diff --git a/src/cli.rs b/src/cli.rs index c10e3ca6c..130cd35b9 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,4 +1,5 @@ use camino::Utf8PathBuf; +use lazycell::AtomicLazyCell; use reqwest::blocking::Client; use serde::Serialize; use structopt::{clap::AppSettings, StructOpt}; @@ -6,7 +7,7 @@ use structopt::{clap::AppSettings, StructOpt}; use crate::command::output::JsonOutput; use crate::command::{self, RoverOutput}; use crate::utils::{ - client::StudioClientConfig, + client::{get_configured_client, StudioClientConfig}, env::{RoverEnv, RoverEnvKey}, stringify::option_from_display, version, @@ -66,13 +67,40 @@ pub struct Rover { #[structopt(long = "output", default_value = "plain", possible_values = &["json", "plain"], case_insensitive = true, global = true)] output_type: OutputType, + /// Accept invalid certificates when performing HTTPS requests. + /// + /// You should think very carefully before using this flag. + /// + /// If invalid certificates are trusted, any certificate for any site will be trusted for use. + /// This includes expired certificates. + /// This introduces significant vulnerabilities, and should only be used as a last resort. + #[structopt( + long = "insecure-accept-invalid-certs", + case_insensitive = true, + global = true + )] + accept_invalid_certs: bool, + + /// Accept invalid hostnames when performing HTTPS requests. + /// + /// You should think very carefully before using this flag. + /// + /// If hostname verification is not used, any valid certificate for any site will be trusted for use from any other. + /// This introduces a significant vulnerability to man-in-the-middle attacks. + #[structopt( + long = "insecure-accept-invalid-hostnames", + case_insensitive = true, + global = true + )] + accept_invalid_hostnames: bool, + #[structopt(skip)] #[serde(skip_serializing)] pub(crate) env_store: RoverEnv, #[structopt(skip)] #[serde(skip_serializing)] - client: Client, + client: AtomicLazyCell, } impl Rover { @@ -214,8 +242,20 @@ impl Rover { } pub(crate) fn get_reqwest_client(&self) -> Client { - // we can use clone here freely since `reqwest` uses an `Arc` under the hood - self.client.clone() + // return a clone of the underlying client if it's already been populated + if let Some(client) = self.client.borrow() { + // we can use clone here freely since `reqwest` uses an `Arc` under the hood + client.clone() + } else { + // if a request hasn't been made yet, this cell won't be populated yet + self.client + .fill( + get_configured_client(self.accept_invalid_certs, self.accept_invalid_hostnames) + .expect("Could not configure the request client"), + ) + .expect("Could not overwrite the existing request client"); + self.get_reqwest_client() + } } } diff --git a/src/utils/client.rs b/src/utils/client.rs index 574c9799b..94f24ac05 100644 --- a/src/utils/client.rs +++ b/src/utils/client.rs @@ -8,6 +8,19 @@ use rover_client::blocking::StudioClient; /// the Apollo graph registry's production API endpoint const STUDIO_PROD_API_ENDPOINT: &str = "https://graphql.api.apollographql.com/api/graphql"; +pub(crate) fn get_configured_client( + accept_invalid_certs: bool, + accept_invalid_hostnames: bool, +) -> Result { + let client = Client::builder() + .gzip(true) + .brotli(true) + .danger_accept_invalid_certs(accept_invalid_certs) + .danger_accept_invalid_hostnames(accept_invalid_hostnames) + .build()?; + Ok(client) +} + pub struct StudioClientConfig { pub(crate) config: config::Config, client: Client, From 3561f2a6989769a856d5ed0a544c8d469c7ae36f Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Wed, 22 Sep 2021 11:58:58 -0500 Subject: [PATCH 2/3] s/SSL\/TLS/TLS\/SSL Co-authored-by: Jesse Rosenberger --- docs/source/configuring.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/configuring.md b/docs/source/configuring.md index 3abb13d86..1a0e959f6 100644 --- a/docs/source/configuring.md +++ b/docs/source/configuring.md @@ -265,7 +265,7 @@ If you use a version control system besides Git, you can use the environment var Currently, only Git is fully supported by Apollo Studio. -## Bypass SSL/TLS Validation +## Bypass TLS/SSL Validation Sometimes, you may want to perform HTTPS requests from Rover, but skip validation checks. This is generally not recommended and insecure, but there are two flags you can use to configure how Rover validates HTTPS requests. From b332b228f026d4de212fac03298529ff341cf7aa Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Wed, 22 Sep 2021 11:59:38 -0500 Subject: [PATCH 3/3] better docs for communicating "insecure" flag tradeoffs Co-authored-by: Jesse Rosenberger --- docs/source/configuring.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/source/configuring.md b/docs/source/configuring.md index 1a0e959f6..5e27c79b7 100644 --- a/docs/source/configuring.md +++ b/docs/source/configuring.md @@ -267,12 +267,11 @@ Currently, only Git is fully supported by Apollo Studio. ## Bypass TLS/SSL Validation -Sometimes, you may want to perform HTTPS requests from Rover, but skip validation checks. This is generally not recommended and insecure, but there are two flags you can use to configure how Rover validates HTTPS requests. +In some configurations (often on internal networks) users may need Rover to communicate over encrypted channels (e.g., HTTPS) but avoid the more stringent digital certificate verifications which validate hostnames or may even wish to bypass the digital certificate validation entirely. This is generally not recommended and considered to be much less secure but for cases where it's necessary, there are two flags you can use to configure how Rover validates HTTPS requests: -The `--insecure-accept-invalid-hostnames` flag will disable hostname validation. If hostname verification is not used, any valid certificate for any site will be trusted for use from any other. This introduces a significant vulnerability to man-in-the-middle attacks. - -The `--insecure-accept-invalid-certs` flag will disable certificate validation. If invalid certificates are trusted, any certificate for any site will be trusted for use. This includes expired certificates. This introduces significant vulnerabilities, and should only be used as a last resort. +- The `--insecure-accept-invalid-hostnames` flag will disable hostname validation. If hostname verification is not used, any valid certificate for any site will be trusted for use from any other. This introduces a significant vulnerability to man-in-the-middle attacks. +- The `--insecure-accept-invalid-certs` flag will disable certificate validation. If invalid certificates are trusted, any certificate for any site will be trusted for use. This includes expired certificates. This introduces significant vulnerabilities, and should only be used as a last resort. ## Supported environment variables You can configure Rover's behavior by setting the environment variables listed below.