Skip to content

Commit

Permalink
fix: Protect BasicAuth::password from being printed (#5195)
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitry Murzin <[email protected]>
  • Loading branch information
dima74 authored Oct 28, 2024
1 parent ac0ec33 commit d2846a3
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 6 deletions.
14 changes: 10 additions & 4 deletions crates/iroha/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,11 @@ impl Client {
mut headers: HashMap<String, String>,
) -> Self {
if let Some(basic_auth) = basic_auth {
let credentials = format!("{}:{}", basic_auth.web_login, basic_auth.password);
let credentials = format!(
"{}:{}",
basic_auth.web_login,
basic_auth.password.expose_secret()
);
let engine = base64::engine::general_purpose::STANDARD;
let encoded = base64::engine::Engine::encode(&engine, credentials);
headers.insert(String::from("Authorization"), format!("Basic {encoded}"));
Expand Down Expand Up @@ -974,11 +978,13 @@ mod blocks_api {

#[cfg(test)]
mod tests {
use iroha_primitives::small::SmallStr;
use iroha_test_samples::gen_account_in;

use super::*;
use crate::config::{BasicAuth, Config};
use crate::{
config::{BasicAuth, Config},
secrecy::SecretString,
};

const LOGIN: &str = "mad_hatter";
const PASSWORD: &str = "ilovetea";
Expand Down Expand Up @@ -1035,7 +1041,7 @@ mod tests {
let client = Client::new(Config {
basic_auth: Some(BasicAuth {
web_login: LOGIN.parse().expect("Failed to create valid `WebLogin`"),
password: SmallStr::from_str(PASSWORD),
password: SecretString::new(PASSWORD.to_owned()),
}),
..config_factory()
});
Expand Down
6 changes: 4 additions & 2 deletions crates/iroha/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ mod user;

pub use user::Root as UserConfig;

use crate::secrecy::SecretString;

#[allow(missing_docs)]
pub const DEFAULT_TRANSACTION_TIME_TO_LIVE: Duration = Duration::from_secs(100);
#[allow(missing_docs)]
Expand Down Expand Up @@ -49,12 +51,12 @@ impl FromStr for WebLogin {
}

/// Basic Authentication credentials
#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq)]
#[derive(Clone, Deserialize, Serialize, Debug)]
pub struct BasicAuth {
/// Login for Basic Authentication
pub web_login: WebLogin,
/// Password for Basic Authentication
pub password: SmallStr,
pub password: SecretString,
}

/// Complete client configuration
Expand Down
1 change: 1 addition & 0 deletions crates/iroha/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod config;
pub mod http;
mod http_default;
pub mod query;
mod secrecy;

pub use iroha_crypto as crypto;
pub use iroha_data_model as data_model;
27 changes: 27 additions & 0 deletions crates/iroha/src/secrecy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use std::fmt;

use derive_more::Constructor;
use serde::{Deserialize, Serialize, Serializer};

#[derive(Clone, Deserialize, Constructor)]
pub struct SecretString(String);

impl SecretString {
pub fn expose_secret(&self) -> &str {
&self.0
}
}

const REDACTED: &'static str = "[REDACTED]";

impl Serialize for SecretString {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
REDACTED.serialize(serializer)
}
}

impl fmt::Debug for SecretString {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
REDACTED.fmt(f)
}
}

0 comments on commit d2846a3

Please sign in to comment.