Skip to content

[TT-431] Authorization token should not be recorded in detailed logs#8500

Open
MaciekMis wants to merge 4 commits into
masterfrom
TT-431-authorization-token-should-not-be-recorded-in-detailed-logs
Open

[TT-431] Authorization token should not be recorded in detailed logs#8500
MaciekMis wants to merge 4 commits into
masterfrom
TT-431-authorization-token-should-not-be-recorded-in-detailed-logs

Conversation

@MaciekMis

@MaciekMis MaciekMis commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

…n recording raw request.

Description

Related Issue

Motivation and Context

How This Has Been Tested

Screenshots (if appropriate)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Refactoring or add test (improvements in base code or adds test coverage to functionality)

Checklist

  • I ensured that the documentation is up to date
  • I explained why this PR updates go.mod in detail with reasoning why it's required
  • I would like a code coverage CI quality gate exception and have explained why

Ticket Details

TT-431
Status In Dev
Summary Authorization token should not be recorded in detailed logs

Generated at: 2026-07-21 12:06:21

@probelabs

probelabs Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

This pull request enhances security by default by preventing sensitive authorization tokens from being recorded in detailed request logs. A new configuration flag, allow_unsafe_detailed_logs, is introduced, which defaults to false to enable this new secure behavior. Setting it to true restores the legacy functionality of logging raw, unobfuscated requests, providing a backward compatibility option.

The core change involves refactoring the request logging logic into a new gateway/analytics_helper.go file. This new module centralizes the process of preparing a request for detailed logging. It dynamically identifies authorization headers from the API definition and obfuscates their values before the request is serialized. The original request headers are immediately restored after serialization to ensure that the request processing pipeline remains unaffected. The existing success and error handlers (gateway/handler_success.go and gateway/handler_error.go) have been updated to use this new centralized function. Comprehensive unit tests have been added in gateway/analytics_helper_test.go to validate the new obfuscation logic and ensure headers are correctly restored.

Files Changed Analysis

  • cli/linter/schema.json & config/config.go: These files introduce the new boolean configuration flag allow_unsafe_detailed_logs to the gateway's configuration schema and struct, respectively. The default is false, enabling token obfuscation.
  • gateway/analytics_helper.go (New File): This new file centralizes the core logic for detailed request logging. It contains getRawRequest to prepare the request for logging, obfuscateAuthorizationHeaders to redact sensitive tokens, and the refactored recordDetail function to determine if detailed logging is enabled.
  • gateway/analytics_helper_test.go (New File): Adds extensive unit tests for the new header obfuscation logic, covering various authentication configurations, the new config flag, and ensuring that original request headers are properly restored after logging.
  • gateway/handler_error.go & gateway/handler_success.go: These handlers are simplified by replacing inline request serialization logic with a single call to the new getRawRequest helper function. The recordDetail function was also removed from handler_success.go as part of the refactoring.
  • gateway/handler_success_test.go: The test cases for recordDetail were moved from this file to analytics_helper_test.go to align with the code refactoring.

Architecture & Impact Assessment

  • What this PR accomplishes: It significantly improves the default security posture of the gateway by preventing sensitive credentials (e.g., API keys, JWTs) from being exposed in detailed analytics logs.
  • Key technical changes introduced:
    • A new security-by-default configuration (allow_unsafe_detailed_logs: false).
    • Centralization of the request serialization and sanitization logic into a new helper module (gateway/analytics_helper.go).
    • Implementation of a header obfuscation mechanism that dynamically identifies auth headers from the API definition (spec.Auth and spec.AuthConfigs).
    • The request object's headers are only mutated temporarily for logging and are immediately restored, ensuring no side effects on the request lifecycle.
  • Affected system components:
    • Gateway Analytics: The data recorded for detailed logging is now sanitized by default.
    • Configuration: A new global configuration option is available in tyk.conf.
    • Logging/Analytics Sink: Any downstream system consuming detailed logs (e.g., Elasticsearch, Splunk, Mongo) will now receive obfuscated tokens (***) instead of real ones unless explicitly configured otherwise.

Request Logging Flow

sequenceDiagram
    participant Client
    participant Gateway as Tyk Gateway
    participant Handler as Success/Error Handler
    participant AnalyticsHelper as analytics_helper.go
    participant AnalyticsDB as Analytics DB

    Client->>Gateway: Request with Auth Header
    Gateway->>Handler: Process Request
    alt Detailed Recording Enabled
        Handler->>AnalyticsHelper: getRawRequest(r, spec)
        Note right of AnalyticsHelper: If allow_unsafe_detailed_logs is false
        AnalyticsHelper->>AnalyticsHelper: obfuscateAuthorizationHeaders(r, spec)
        AnalyticsHelper-->>Handler: Sanitized Raw Request
        Handler->>AnalyticsDB: Store Sanitized Log
    end
    Handler-->>Gateway: Response
    Gateway-->>Client: Response
Loading

Scope Discovery & Context Expansion

This change is primarily contained within the gateway's analytics recording subsystem. The main impact is on the data persisted in the analytics database and any external systems that ingest these logs. Users relying on detailed logs for debugging authentication issues will now see *** instead of the actual token, which is the intended security outcome.

However, the current implementation has a potential scope limitation:

  • Token Location: The obfuscation logic currently only targets HTTP headers. Tyk also supports authentication tokens passed via query parameters (use_param) and cookies (use_cookie). The current changes do not obfuscate tokens in these locations, meaning they could still be logged in plain text. Future work should extend the sanitization logic to cover these authentication methods as well.
  • Performance: The list of authorization headers to obfuscate is recalculated on every request. For high-throughput environments, it would be more performant to pre-calculate this list when the API specification is first loaded and cache it within the APISpec struct.

Further investigation could involve a broader audit of the codebase for any other instances of request logging that might not use this new centralized and sanitized function.

Metadata
  • Review Effort: 2 / 5
  • Primary Label: enhancement

Powered by Visor from Probelabs

Last updated: 2026-07-21T12:07:24.179Z | Triggered by: pr_updated | Commit: 6c83b34

💡 TIP: You can chat with Visor using /visor ask <your question>

@probelabs

probelabs Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

✅ Architecture Check Passed

No architecture issues found – changes LGTM.

Performance Issues (1)

Severity Location Issue
🟡 Warning gateway/analytics_helper.go:33-68
The list of authorization headers to obfuscate is recalculated on every request when detailed logging is enabled. This computation involves creating a new slice, iterating over the API's authentication configuration map, and performing string manipulations for each header. Since this list is derived from the API definition, which is static between reloads, it can be pre-computed and cached to reduce per-request CPU and memory overhead.
💡 SuggestionPre-compute the list of canonicalized authorization header names when the `APISpec` is loaded and store it in a new field within the `APISpec` struct. The `obfuscateAuthorizationHeaders` function should then use this cached list, avoiding repeated computations and allocations in the request path. This will improve performance for APIs that have detailed request logging enabled.
\n\n

✅ Architecture Check Passed

No architecture issues found – changes LGTM.

\n\n

Performance Issues (1)

Severity Location Issue
🟡 Warning gateway/analytics_helper.go:33-68
The list of authorization headers to obfuscate is recalculated on every request when detailed logging is enabled. This computation involves creating a new slice, iterating over the API's authentication configuration map, and performing string manipulations for each header. Since this list is derived from the API definition, which is static between reloads, it can be pre-computed and cached to reduce per-request CPU and memory overhead.
💡 SuggestionPre-compute the list of canonicalized authorization header names when the `APISpec` is loaded and store it in a new field within the `APISpec` struct. The `obfuscateAuthorizationHeaders` function should then use this cached list, avoiding repeated computations and allocations in the request path. This will improve performance for APIs that have detailed request logging enabled.
\n\n ### ✅ Quality Check Passed

No quality issues found – changes LGTM.


Powered by Visor from Probelabs

Last updated: 2026-07-21T12:07:20.467Z | Triggered by: pr_updated | Commit: 6c83b34

💡 TIP: You can chat with Visor using /visor ask <your question>

@sentinelone-cnapp-eu1

Copy link
Copy Markdown

SentinelOne CNS Hardcoded Secret Detector
✅ Congratulations, your code is safe

SentinelOne CNS is a cloud-agnostic, agentless CSPM & CWPP solution that continuously detects and prevents vulnerabilities that have the highest probability of being exploited in Azure, AWS, Google Cloud, and Kubernetes.

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

💡 Need a hand with PR review? Try Gitar by Sonar!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant