Add SensitiveUrl to redact user secrets from endpoints (#2326)

## Issue Addressed

#2276 

## Proposed Changes

Add the `SensitiveUrl` struct which wraps `Url` and implements custom `Display` and `Debug` traits to redact user secrets from being logged in eth1 endpoints, beacon node endpoints and metrics.

## Additional Info

This also includes a small rewrite of the eth1 crate to make requests using `Url` instead of `&str`. 
Some error messages have also been changed to remove `Url` data.
This commit is contained in:
Mac L
2021-05-04 01:59:51 +00:00
parent 2ccb358d87
commit 4cc613d644
38 changed files with 362 additions and 143 deletions

View File

@@ -13,3 +13,4 @@ reqwest = { version = "0.11.0", features = ["json"] }
serde = { version = "1.0.116", features = ["derive"] }
tokio = { version = "1.1.0", features = ["time"] }
types = { path = "../../consensus/types" }
sensitive_url = { path = "../sensitive_url" }

View File

@@ -4,17 +4,18 @@ use crate::{
};
use reqwest::StatusCode;
pub use reqwest::Url;
use sensitive_url::SensitiveUrl;
use types::{Domain, Fork, Hash256};
/// A wrapper around `reqwest::Client` which provides convenience methods
/// to interface with a BLS Remote Signer.
pub struct RemoteSignerHttpConsumer {
client: reqwest::Client,
server: Url,
server: SensitiveUrl,
}
impl RemoteSignerHttpConsumer {
pub fn from_components(server: Url, client: reqwest::Client) -> Self {
pub fn from_components(server: SensitiveUrl, client: reqwest::Client) -> Self {
Self { client, server }
}
@@ -43,7 +44,7 @@ impl RemoteSignerHttpConsumer {
));
}
let mut path = self.server.clone();
let mut path = self.server.full.clone();
path.path_segments_mut()
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
.push("sign")

View File

@@ -20,10 +20,11 @@
//!
//! ```
//! use remote_signer_consumer::RemoteSignerHttpConsumer;
//! use reqwest::{ClientBuilder, Url};
//! use reqwest::ClientBuilder;
//! use sensitive_url::SensitiveUrl;
//! use tokio::time::Duration;
//!
//! let url: Url = "http://127.0.0.1:9000".parse().unwrap();
//! let url = SensitiveUrl::parse("http://127.0.0.1:9000").unwrap();
//! let reqwest_client = ClientBuilder::new()
//! .timeout(Duration::from_secs(2))
//! .build()
@@ -115,6 +116,7 @@ mod http_client;
pub use http_client::RemoteSignerHttpConsumer;
pub use reqwest::Url;
use sensitive_url::SensitiveUrl;
use serde::{Deserialize, Serialize};
use types::{AttestationData, BeaconBlock, Domain, Epoch, EthSpec, Fork, Hash256, SignedRoot};
@@ -125,7 +127,7 @@ pub enum Error {
/// The server returned an error message where the body was able to be parsed.
ServerMessage(String),
/// The supplied URL is badly formatted. It should look something like `http://127.0.0.1:5052`.
InvalidUrl(Url),
InvalidUrl(SensitiveUrl),
/// The supplied parameter is invalid.
InvalidParameter(String),
}

View File

@@ -1,7 +1,8 @@
mod post {
use remote_signer_consumer::{Error, RemoteSignerHttpConsumer};
use remote_signer_test::*;
use reqwest::{ClientBuilder, Url};
use reqwest::ClientBuilder;
use sensitive_url::SensitiveUrl;
use tokio::time::Duration;
#[test]
@@ -53,7 +54,7 @@ mod post {
let (test_signer, _tmp_dir) = set_up_api_test_signer_to_sign_message();
let run_testcase = |u: &str| -> Result<String, String> {
let url: Url = u.parse().map_err(|e| format!("[ParseError] {:?}", e))?;
let url = SensitiveUrl::parse(u).map_err(|e| format!("{:?}", e))?;
let reqwest_client = ClientBuilder::new()
.timeout(Duration::from_secs(12))
@@ -66,7 +67,7 @@ mod post {
let signature = do_sign_request(&test_client, test_input);
signature.map_err(|e| match e {
Error::InvalidUrl(message) => format!("[InvalidUrl] {:?}", message),
Error::InvalidUrl(message) => format!("{:?}", message),
Error::Reqwest(re) => {
if re.is_builder() {
format!("[Reqwest - Builder] {:?}", re.url().unwrap())
@@ -84,25 +85,22 @@ mod post {
// url::parser::ParseError.
// These cases don't even make it to the step of building a RemoteSignerHttpConsumer.
testcase("", "[ParseError] RelativeUrlWithoutBase");
testcase("/4/8/15/16/23/42", "[ParseError] RelativeUrlWithoutBase");
testcase("localhost", "[ParseError] RelativeUrlWithoutBase");
testcase(":", "[ParseError] RelativeUrlWithoutBase");
testcase("0.0:0", "[ParseError] RelativeUrlWithoutBase");
testcase(":aa", "[ParseError] RelativeUrlWithoutBase");
testcase("0:", "[ParseError] RelativeUrlWithoutBase");
testcase("ftp://", "[ParseError] EmptyHost");
testcase("http://", "[ParseError] EmptyHost");
testcase("http://127.0.0.1:abcd", "[ParseError] InvalidPort");
testcase("http://280.0.0.1", "[ParseError] InvalidIpv4Address");
testcase("", "ParseError(RelativeUrlWithoutBase)");
testcase("/4/8/15/16/23/42", "ParseError(RelativeUrlWithoutBase)");
testcase("localhost", "ParseError(RelativeUrlWithoutBase)");
testcase(":", "ParseError(RelativeUrlWithoutBase)");
testcase("0.0:0", "ParseError(RelativeUrlWithoutBase)");
testcase(":aa", "ParseError(RelativeUrlWithoutBase)");
testcase("0:", "ParseError(RelativeUrlWithoutBase)");
testcase("ftp://", "ParseError(EmptyHost)");
testcase("http://", "ParseError(EmptyHost)");
testcase("http://127.0.0.1:abcd", "ParseError(InvalidPort)");
testcase("http://280.0.0.1", "ParseError(InvalidIpv4Address)");
// `Error::InvalidUrl`.
// The RemoteSignerHttpConsumer is created, but fails at `path_segments_mut()`.
testcase(
"localhost:abcd",
"[InvalidUrl] Url { scheme: \"localhost\", username: \"\", password: None, host: None, port: None, path: \"abcd\", query: None, fragment: None }",
);
testcase("localhost:", "[InvalidUrl] Url { scheme: \"localhost\", username: \"\", password: None, host: None, port: None, path: \"\", query: None, fragment: None }");
testcase("localhost:abcd", "InvalidUrl(\"URL cannot be a base.\")");
testcase("localhost:", "InvalidUrl(\"URL cannot be a base.\")");
// `Reqwest::Error` of the `Builder` kind.
// POST is not made.
@@ -130,7 +128,7 @@ mod post {
let (test_signer, _tmp_dir) = set_up_api_test_signer_to_sign_message();
let run_testcase = |u: &str| -> Result<String, String> {
let url: Url = u.parse().unwrap();
let url = SensitiveUrl::parse(u).unwrap();
let reqwest_client = ClientBuilder::new()
.timeout(Duration::from_secs(12))