Repository navigation
PPNA-10000 Redact sensitive values from HTTP/auth debug logs - #38
Conversation
There was a problem hiding this comment.
Pull request overview
Adds redaction safeguards for credentials and sensitive HTTP values in debug logs.
Changes:
- Adds recursive payload and URL query redaction helpers.
- Applies redaction to authentication, request, response, and HTTP error logging.
- Adds tests and changelog documentation.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
piwik_pro_log_analytics/import_logs.py |
Implements and applies log redaction. |
tests/test_main.py |
Tests sensitive-value masking. |
CHANGELOG.md |
Documents the security change. |
Suppressed comments (6)
piwik_pro_log_analytics/import_logs.py:218
- The URL sanitizer preserves
parts.netloc, so credentials in userinfo remain visible; for example,https://user:password@example.com/?token=xstill logsuser:password. Redact the userinfo portion before rebuilding the URL.
parts.netloc,
piwik_pro_log_analytics/import_logs.py:203
- This sanitizer is not applied to
RedirectHandlerWithLoggingat line 1797, which still logsnewurlverbatim. A redirectLocationcontainingtoken_auth, cookies, or another sensitive query parameter therefore bypasses this PR's redaction; apply this helper to that URL before logging it.
def _redact_url_component_for_log(value):
"""Redact sensitive query-string parameters in a URL or path+query string."""
piwik_pro_log_analytics/import_logs.py:1862
- The same HTTP response is logged again without redaction by the
--debug-trackerpath at line 2452. That second log call bypasses this protection and can emit sensitive response fields verbatim; apply_redact_sensitive_for_logthere as well.
logging.debug("Response '%s'" % _redact_sensitive_for_log(result))
piwik_pro_log_analytics/import_logs.py:1834
- These sanitizer calls execute before
logging.debugchecks the log level, so normal non-debug imports now decode, parse, traverse, and re-serialize every JSON request body. For large batched tracking payloads this adds avoidable work on every request; guard the debug block before computing the redacted values.
logging.debug( # codeql[py/clear-text-logging-sensitive-data]
"Request data '%s'" % _redact_sensitive_for_log(data)
piwik_pro_log_analytics/import_logs.py:1862
- This parses, traverses, and serializes every JSON response even when debug logging is disabled, because function arguments are evaluated eagerly. Guard the sanitizer with the debug-level check so production requests do not pay this cost.
logging.debug("Response '%s'" % _redact_sensitive_for_log(result))
piwik_pro_log_analytics/import_logs.py:1827
- Although this request log is sanitized,
Configurationlogs the same user-suppliedpiwik_urlandpiwik_api_urlverbatim at lines 1325 and 1332 before any request is made. Query credentials or URL userinfo therefore still reach debug output; route those two URL log arguments through_redact_url_component_for_logtoo.
logging.debug("Request url '%s'" % _redact_url_component_for_log(url))
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The OAuth token request body carries client_secret, so redacting it in place still leaves the secret one key-name heuristic away from the log (and CodeQL rightly flags the flow). Log only the body type and size.
79f062f to
5868d08
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
Suppressed comments (2)
piwik_pro_log_analytics/import_logs.py:198
- The current implementation still exposes credentials that are valid JSON scalars. For example, a token value of
"12345"is parsed as an integer and serialized back as12345, so the authentication debug log at line 1475 leaks it. Fail closed unless a top-level payload is a keyed object or array that can actually be scrubbed.
try:
parsed = json.loads(value)
except (TypeError, ValueError):
return _REDACTED
try:
return json.dumps(_redact_sensitive_for_log(parsed, as_payload=False))
except (TypeError, ValueError):
return _REDACTED
piwik_pro_log_analytics/import_logs.py:1876
- This redaction runs eagerly even when debug logging is disabled. Consequently every successful API response is parsed, recursively copied, and serialized here, then parsed again by
_call_api; large responses pay this overhead during normal runs. Guard the transformation with the debug-level check.
logging.debug("Response '%s'" % _redact_sensitive_for_log(result))
No description provided.