From 0ed6d82d105390345c6dc3e1e5e86f6f8c3f6189 Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Thu, 23 Mar 2023 11:37:23 -0700 Subject: [PATCH] Defend against configured known secret keys. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a two-prong effort. First, we warn on launch if a known key is used. Second, we document using invalid keys where possible. Co-authored-by: Jonas Møller --- core/lib/src/config/config.rs | 12 ++++++++++++ core/lib/src/config/mod.rs | 2 +- core/lib/src/config/secret_key.rs | 7 ++++++- core/lib/src/rocket.rs | 6 +++++- examples/config/Rocket.toml | 3 ++- site/guide/9-configuration.md | 10 ++++++---- 6 files changed, 32 insertions(+), 8 deletions(-) diff --git a/core/lib/src/config/config.rs b/core/lib/src/config/config.rs index eaca7f16..2920a38c 100644 --- a/core/lib/src/config/config.rs +++ b/core/lib/src/config/config.rs @@ -364,6 +364,18 @@ impl Config { #[cfg(not(feature = "mtls"))] { false } } + #[cfg(feature = "secrets")] + pub(crate) fn known_secret_key_used(&self) -> bool { + const KNOWN_SECRET_KEYS: &'static [&'static str] = &[ + "hPRYyVRiMyxpw5sBB1XeCMN1kFsDCqKvBi2QJxBVHQk=" + ]; + + KNOWN_SECRET_KEYS.iter().any(|&key_str| { + let value = figment::value::Value::from(key_str); + self.secret_key == value.deserialize().expect("known key is valid") + }) + } + pub(crate) fn pretty_print(&self, figment: &Figment) { use crate::log::PaintExt; diff --git a/core/lib/src/config/mod.rs b/core/lib/src/config/mod.rs index 00f0e926..00a2613c 100644 --- a/core/lib/src/config/mod.rs +++ b/core/lib/src/config/mod.rs @@ -666,7 +666,7 @@ mod tests { fn test_no_err_on_release_and_custom_secret_key() { figment::Jail::expect_with(|jail| { jail.set_env("ROCKET_PROFILE", "release"); - let key = "hPRYyVRiMyxpw5sBB1XeCMN1kFsDCqKvBi2QJxBVHQk="; + let key = "Bx4Gb+aSIfuoEyMHD4DvNs92+wmzfQK98qc6MiwyPY4="; let figment = Config::figment().merge(("secret_key", key)); assert!(crate::local::blocking::Client::tracked(crate::custom(&figment)).is_ok()); diff --git a/core/lib/src/config/secret_key.rs b/core/lib/src/config/secret_key.rs index adf7e528..445f9601 100644 --- a/core/lib/src/config/secret_key.rs +++ b/core/lib/src/config/secret_key.rs @@ -22,8 +22,13 @@ enum Kind { /// ```rust /// use rocket::config::Config; /// +/// // NOTE: Don't (!) use this key! Generate your own and keep it private! +/// // e.g. via `head -c64 /dev/urandom | base64` /// let figment = Config::figment() -/// .merge(("secret_key", "hPRYyVRiMyxpw5sBB1XeCMN1kFsDCqKvBi2QJxBVHQk=")); +/// # .merge(("secret_key", "hPRYyVRiMyxpw5sBB1XeCMN1kFsDCqKvBi2QJxBVHQk=")); +/// # /* +/// .merge(("secret_key", "hPrYyЭRiMyµ5sBB1π+CMæ1køFsåqKvBiQJxBVHQk=")); +/// # */ /// /// let config = Config::from(figment); /// assert!(!config.secret_key.is_zero()); diff --git a/core/lib/src/rocket.rs b/core/lib/src/rocket.rs index 03e2021b..2c28f313 100644 --- a/core/lib/src/rocket.rs +++ b/core/lib/src/rocket.rs @@ -530,7 +530,11 @@ impl Rocket { config.secret_key = crate::config::SecretKey::generate() .unwrap_or_else(crate::config::SecretKey::zero); } - }; + } else if config.known_secret_key_used() { + warn!("The configured `secret_key` is exposed and insecure."); + warn_!("The configured key is publicly published and thus insecure."); + warn_!("Try generating a new key with `head -c64 /dev/urandom | base64`."); + } // Initialize the router; check for collisions. let mut router = Router::new(); diff --git a/examples/config/Rocket.toml b/examples/config/Rocket.toml index e6059180..170fad87 100644 --- a/examples/config/Rocket.toml +++ b/examples/config/Rocket.toml @@ -26,7 +26,8 @@ port = 8000 workers = 12 keep_alive = 5 log_level = "critical" -# don't use this key! generate your own and keep it private! +# NOTE: Don't (!) use this key! Generate your own and keep it private! +# e.g. via `head -c64 /dev/urandom | base64` secret_key = "hPRYyVRiMyxpw5sBB1XeCMN1kFsDCqKvBi2QJxBVHQk=" key = "a release app-key" extra = false diff --git a/site/guide/9-configuration.md b/site/guide/9-configuration.md index b77de10e..69797efb 100644 --- a/site/guide/9-configuration.md +++ b/site/guide/9-configuration.md @@ -126,11 +126,12 @@ limits = { json = "10MiB" } port = 9001 ## set only when compiled in release mode, i.e, `cargo build --release` -## don't use this secret_key! generate your own and keep it private! [release] port = 9999 -secret_key = "hPRYyVRiMyxpw5sBB1XeCMN1kFsDCqKvBi2QJxBVHQk=" ip_header = false +# NOTE: Don't (!) use this key! Generate your own and keep it private! +# e.g. via `head -c64 /dev/urandom | base64` +secret_key = "hPrYyЭRiMyµ5sBB1π+CMæ1køFsåqKvBiQJxBVHQk=" ``` The following is a `Rocket.toml` file with all configuration options set for @@ -150,8 +151,9 @@ ip_header = "X-Real-IP" # set to `false` to disable log_level = "normal" temp_dir = "/tmp" cli_colors = true -## NOTE: Don't (!) use this key! Generate your own! -secret_key = "hPRYyVRiMyxpw5sBB1XeCMN1kFsDCqKvBi2QJxBVHQk=" +# NOTE: Don't (!) use this key! Generate your own and keep it private! +# e.g. via `head -c64 /dev/urandom | base64` +secret_key = "hPrYyЭRiMyµ5sBB1π+CMæ1køFsåqKvBiQJxBVHQk=" [default.limits] form = "64 kB"