Skip to content

chore(proxy): print request safety in proxy#1715

Open
CooooolFrog wants to merge 6 commits intodragonflyoss:mainfrom
CooooolFrog:main
Open

chore(proxy): print request safety in proxy#1715
CooooolFrog wants to merge 6 commits intodragonflyoss:mainfrom
CooooolFrog:main

Conversation

@CooooolFrog
Copy link
Copy Markdown

Description

This PR addresses a potential security problem mentioned in this issue (#1559) by changing the output logs for request-related data from the info level to the debug level, thus preventing the direct output of sensitive information.

Related Issue

#1559

@CooooolFrog CooooolFrog force-pushed the main branch 2 times, most recently from 9d5f49f to b344a49 Compare March 11, 2026 08:16
@CooooolFrog CooooolFrog requested a review from gaius-qi March 11, 2026 08:16
@CooooolFrog CooooolFrog added the bug Something isn't working label Mar 11, 2026
@CooooolFrog CooooolFrog force-pushed the main branch 2 times, most recently from ac87ca5 to b49fb44 Compare March 11, 2026 08:38
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 11, 2026

Codecov Report

❌ Patch coverage is 0% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.21%. Comparing base (c6a2b95) to head (16a938f).
⚠️ Report is 18 commits behind head on main.

Files with missing lines Patch % Lines
dragonfly-client/src/proxy/mod.rs 0.00% 21 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1715      +/-   ##
==========================================
- Coverage   50.29%   50.21%   -0.08%     
==========================================
  Files          86       86              
  Lines       21977    21998      +21     
==========================================
- Hits        11053    11046       -7     
- Misses      10924    10952      +28     
Files with missing lines Coverage Δ
dragonfly-client/src/proxy/mod.rs 0.00% <0.00%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Signed-off-by: CooooolFrog <zuliangwanghust@gmail.com>
Signed-off-by: CooooolFrog <zuliangwanghust@gmail.com>
Signed-off-by: CooooolFrog <zuliangwanghust@gmail.com>
Signed-off-by: CooooolFrog <zuliangwanghust@gmail.com>
Signed-off-by: CooooolFrog <zuliangwanghust@gmail.com>
Signed-off-by: CooooolFrog <zuliangwanghust@gmail.com>
Copy link
Copy Markdown
Contributor

@CormickKneey CormickKneey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR — security is indeed important. I've left some review comments.

Additionally, unit tests are essential for this kind of change. Please take a look and address them when you get a chance.

safe_headers,
);

if !sensitive_headers.is_empty() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logs the actual values of Authorization, Cookie, etc.

Recommendation: Log only the header names, not their values. Or redact values to something like [REDACTED].

"x-auth-token",
];

let blacklist_set: HashSet<&str> = HEADER_BLACKLIST.iter().cloned().collect();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This allocates a new HashSet per invocation. For a proxy that handles high request volume, this is unnecessary overhead.

With only 6 entries, a linear scan over the const slice is actually faster.

"{} | method={}, uri={}, version={:?}, safe_headers={:?}",
log_info,
request.method(),
request.uri(),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Query strings often carry tokens (?token=xxx, ?access_key=xxx). This should either be sanitized or at least called out as a known limitation.

let (mut safe_headers, mut sensitive_headers) = (Vec::new(), Vec::new());
for (name, value) in request.headers().iter() {
if blacklist_set.contains(&name.as_str()) {
sensitive_headers.push((name, value));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to allocate a Vec, you can use a bool flag like this for better performance:

let sensitive_names: Vec<&str> = request.headers().keys()
    .filter(|name| SENSITIVE_HEADERS.contains(&name.as_str()))
    .map(|name| name.as_str())
    .collect();

if !sensitive_names.is_empty() {
    debug!("{} | redacted sensitive headers: {:?}", log_info, sensitive_names);
}

.boxed()
}

/// log_request safely output information from the request through logs
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

capitalize first word


/// log_request safely output information from the request through logs
fn log_request(request: &Request<hyper::body::Incoming>, log_info: &str) {
const HEADER_BLACKLIST: &[&str] = &[
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing commonly sensitive headers:

  • x-api-key
  • x-csrf-token / x-xsrf-token
  • www-authenticate (may leak auth scheme details)
  • x-forwarded-for (PII — client IP)

Consider whether an allowlist approach (log only known-safe headers) would be more secure than a blocklist, which requires ongoing maintenance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants