Skip to content

Commit eae289f

Browse files
committed
fix: redact sensitive headers in tonic debug logs
Adds function that ensures headers that look sensitive are redacted, to be used inside debug logs. Attempted a parameterised test but `run_env_test` only accepts static strings for env vars.
1 parent cef3317 commit eae289f

1 file changed

Lines changed: 41 additions & 2 deletions

File tree

  • opentelemetry-otlp/src/exporter/tonic

opentelemetry-otlp/src/exporter/tonic/mod.rs

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,9 @@ impl TonicExporterBuilder {
231231

232232
let compression = self.resolve_compression(signal_compression_var)?;
233233

234-
let (headers_from_env, headers_for_logging) = parse_headers_from_env(signal_headers_var);
234+
let (headers_from_env, all_headers) = parse_headers_from_env(signal_headers_var);
235+
let headers_for_logging = redact_sensitive_headers(all_headers);
236+
235237
let metadata = merge_metadata_with_headers_from_env(
236238
self.tonic_config.metadata.unwrap_or_default(),
237239
headers_from_env,
@@ -608,6 +610,25 @@ fn parse_headers_from_env(signal_headers_var: &str) -> (HeaderMap, Vec<(String,
608610
)
609611
}
610612

613+
fn redact_sensitive_headers(headers: Vec<(String, String)>) -> Vec<(String, String)> {
614+
headers
615+
.iter()
616+
.map(|(k, v)| {
617+
let header_name = k.to_lowercase();
618+
let value = v.to_lowercase();
619+
if header_name.contains("auth")
620+
|| header_name.contains("api-key")
621+
|| header_name.contains("token")
622+
|| value.contains("bearer")
623+
{
624+
(k.clone(), "[REDACTED]".to_string())
625+
} else {
626+
(k.clone(), v.clone())
627+
}
628+
})
629+
.collect()
630+
}
631+
611632
/// Expose interface for modifying [TonicConfig] fields within the exporter builders.
612633
pub(crate) trait HasTonicConfig {
613634
/// Return a mutable reference to the export config within the exporter builders.
@@ -807,7 +828,7 @@ impl<B: HasTonicConfig> WithTonicConfig for B {
807828
#[cfg(test)]
808829
mod tests {
809830
use crate::exporter::tests::run_env_test;
810-
use crate::exporter::tonic::WithTonicConfig;
831+
use crate::exporter::tonic::{redact_sensitive_headers, WithTonicConfig};
811832
#[cfg(feature = "grpc-tonic")]
812833
use crate::exporter::Compression;
813834
use crate::{TonicExporterBuilder, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT};
@@ -981,6 +1002,24 @@ mod tests {
9811002
);
9821003
}
9831004

1005+
#[test]
1006+
fn test_sensitive_headers_redacted() {
1007+
run_env_test(
1008+
vec![(
1009+
OTEL_EXPORTER_OTLP_HEADERS,
1010+
"authorization=Bearer my-secret-token",
1011+
)],
1012+
|| {
1013+
let headers_from_env = super::parse_headers_from_env(OTEL_EXPORTER_OTLP_HEADERS);
1014+
let redacted = redact_sensitive_headers(headers_from_env.1);
1015+
1016+
let (_, header_value) =
1017+
redacted.iter().find(|(k, _)| k == "authorization").unwrap();
1018+
assert_eq!(*header_value, "[REDACTED]".to_string())
1019+
},
1020+
);
1021+
}
1022+
9841023
#[test]
9851024
fn test_priority_of_signal_env_over_generic_env_for_endpoint() {
9861025
run_env_test(

0 commit comments

Comments
 (0)