debug: redact sensitive info from debug logs#27579
debug: redact sensitive info from debug logs#27579tsaarni wants to merge 4 commits intoenvoyproxy:mainfrom
Conversation
|
I know that in #9652 @mattklein123 explicitly asks for design proposal and I'm submitting code PR instead. Sorry for that 😳 After looking at previous related issues (linked in the description) I felt it would be overwhelmingly complicated to propose e.g. a new extension points for this purpose. It seems to me that there isn't natural way to configure and control such extensions that do not naturally "fit" into the XDS API, like application logging . I was also curious for feedback for a "trivial" approach where masking sensitive information would be targeted to cookies and query string in a hardcoded way, and controlled by runtime guard. |
Redact potentially sensitive information from debug logs by masking - query string - authorization header value - cookie values Signed-off-by: Tero Saarni <tero.saarni@est.tech>
fd7bf0e to
4cb131b
Compare
|
This should not be enabled by default since debug.log is a developer tool. This needs to be enabled explicitly for people that write debug log for production traffic. Also this is very brittle. You have fixed one place where header map is printed in log, but there are others and people may add more in the future. It should probably be a part of the output operator of the header map. /wait |
|
Thank you @yanavlasov!
Would using
As the first alternative, I attempted to add this in Would you have any suggestions for me from this perspective? |
Many, but not all libraries that depend on |
Signed-off-by: Tero Saarni <tero.saarni@est.tech>
|
I have now negated the feature flag. It is now called Rationale: I did not add the feature behind This approach might still be slight misuse of RUNTIME_GUARD. Adding new guards is described in context of adding new features. When it comes to alternative ways of enabling the feature: I assume new command line flags are discouraged so I will not propose putting this behind new command line flag. And debug level names seem come from the log library, so I will not propose new level, such as
I still have no solution for moving functionality from |
Call Http::Utilities for dumping HeaderMap, to make it possible to redact potentially sensitive headers. Signed-off-by: Tero Saarni <tero.saarni@est.tech>
Signed-off-by: Tero Saarni <tero.saarni@est.tech>
As a straightforward workaround, I've just added forward declaration to call |
| headers.iterate([&os, spaces = spacesForLevel(indent_level)]( | ||
| const HeaderEntry& header) -> HeaderMap::Iterate { | ||
| os << spaces << "'" << header.key().getStringView() << "', '"; | ||
| if (header.key() == Http::Headers::get().Path) { |
There was a problem hiding this comment.
This is where the spec would come in handy. Why sanitize just these headers? This change looks to be specific to your requirements. The main concern is that this code would get bigger and bigger as different people would need different headers to be sanitized.
I think the list of headers needs to be determined by configuration, which is how this feature needs to be enabled too. Runtime flag is not a good choice here.
One approach is to define a bootstrap extension for printing header map into the debug log. You can then override it for your product to sanitize the header map the way you want. You can also implement an extension that takes the list of headers that are removed from the log.
There was a problem hiding this comment.
This is where the spec would come in handy.
What type of spec could it be?
For masking three headers addressed in this PR currently, there was a need to write three different parsers: redacting query string, redacting cookie values, redacting complete header.
Would the spec then provide means for user to
- apply pre-defined / fixed parsers to mask given headers?
- add their own "custom masking" extensions written in C++ (like access log formatters)?
To me (1) sounds reasonable, although only "redact complete header" is generic enough to be applied to any random header.
I guess otherwise we end up in (2) allowing user to write application specific logic, to mask application specific headers. It sounds bit complicated and it might be unlikely people would utilize it that much. After all, masking debug log is quite a rare use case.
This change looks to be specific to your requirements.
I thought the proposed headers were the obvious ones, which would apply to most, not only my requirements.
But I agree, any X-MyExampleApp-Token type of header could contain sensitive information as well.
There was a problem hiding this comment.
Just a GitHub Issue with a short description of how a feature is going to be implemented is enough.
The key is flexibility. Envoy achieves this through extensions. I think the first step is create an extension point with API - interface with a method that takes header map as a parameter and returns formatted string. This can then plumbed into the header map.
Then you can build on top of this to add functionality that you need. I.e. list of headers that need to be redacted, boolean flag to redact query, cookies, etc. You can add regex matchers, whatever suits your purpose.
This is one of the possible solutions, other maintains may suggest simpler things. The Issue with the spec would help define the solution that meets community needs.
|
This change seems extremely fragile to me and of dubious utility given how many places sensitive information might come out. Can you just route the logs in your environment through some scrubber that parses them and filters? |
Hi @mattklein123! I've added a design doc here #27820. Do I interpret it correctly that anything that could be addressed there will not change the situation, and that #9652 should rather be closed as will-not-implement? #9652 was specifically about redacting headers, which are centrally handled by |
|
I'm mostly saying that I agree with @yanavlasov comments that these feels like a very specific change to deal with a single case of a problem, when in fact there will be many more cases in practice. It just seems like this is better handled as a wrapper in your own environment rather than changes to Envoy. If other maintainers strongly agree this is useful I'm happy to be swayed. |
|
Going to close this out for now given the discussion. We can reopen if there is strong support from other maintainers to go this route. |
Redact potentially sensitive information from debug logs by masking query string and cookie values.
Fix #9652
Additional Description:
While doing troubleshooting it might be necessary to collect, distribute and store debug level logs from Envoy. It introduces a risk of unintended data leakage, where sensitive information is revealed accidentally as part of the log files to people who should not have access to that data. Most typically, this would happen through authorization header, cookies and query string value, dumped in the log files.
See example of a log entry revealing sensitive information:
This PR proposes an approach where sensitive information is masked by adding
[redacted]in place of potentially sensitive values:Any custom header
X-MyExampleApp-Tokenmight potentially also contain sensitive information, but it would require rather elaborate configuration support to handle. This case is not considered by this PR.The proposed functionality is implemented in
Http::Utilitiessince it contains functions for header parsing. Adding explicit dependency fromHttp::HeaderMaptoHttp::Utilitieswould introduce cyclic dependency, therefore forward declaration was used.The PR adds runtime guard
envoy.reloadable_features.debug_include_sensitive_datawhich keeps the current behavior unchanged. All headers, even sensitive ones, are printed to debug log as they are. Setting the value tofalseenables redacting sensitive headers.Here is a list of older issue where sensitive information was redacted from various printouts:
:PATHin access logs without query string #7583, formatter: print request header without query string #15711Risk Level: Low
Testing:
TBD
Docs Changes:
Added chapter to "Application logging" configuration chapter, documenting the runtime feature flag.
Release Notes:
debug: sensitive headers can be redacted from debug logs by setting
envoy.reloadable_features.debug_include_sensitive_dataruntime guard to false.