From 1af66d67449e59072ef104f09216d398fdde3114 Mon Sep 17 00:00:00 2001 From: sigoden Date: Sat, 25 Apr 2026 18:51:21 +0800 Subject: [PATCH] fix: escape control chars in logged URI and headers (#691) --- src/http_logger.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/http_logger.rs b/src/http_logger.rs index 9e466b4..099d6ef 100644 --- a/src/http_logger.rs +++ b/src/http_logger.rs @@ -30,7 +30,9 @@ impl HttpLogger { LogElement::Variable(name) => match name.as_str() { "request" => { let uri = req.uri().to_string(); - let uri = decode_uri(&uri).map(|s| s.to_string()).unwrap_or(uri); + let uri = decode_uri(&uri) + .map(|s| sanitize_log_value(&s)) + .unwrap_or(uri); data.insert(name.to_string(), format!("{} {uri}", req.method())); } "remote_user" => { @@ -44,7 +46,7 @@ impl HttpLogger { }, LogElement::Header(name) => { if let Some(value) = req.headers().get(name).and_then(|v| v.to_str().ok()) { - data.insert(name.to_string(), value.to_string()); + data.insert(name.to_string(), sanitize_log_value(value)); } } LogElement::Literal(_) => {} @@ -104,3 +106,15 @@ impl FromStr for HttpLogger { Ok(Self { elements }) } } + +fn sanitize_log_value(s: &str) -> String { + s.chars() + .flat_map(|c| { + if c.is_control() { + format!("\\x{:02x}", c as u32).chars().collect::>() + } else { + vec![c] + } + }) + .collect() +}