Skip to content

Security: Sensitive information disclosure in response output #35

@sgaunet

Description

@sgaunet

Description

Authorization headers and environment variables (including potential secrets) are echoed in plain text in the response, creating an information disclosure risk.

Location

  • http-echo.go:144-148 - Authorization header printed
  • http-echo.go:213-218 - Environment variables echoed
// Line 144: Authorization in "important headers"
importantHeaders := []string{"Content-Type", "Content-Length", "Authorization", "Accept", "Accept-Encoding"}

// Lines 213-218: Environment variables printed
envVars := []string{"HOSTNAME", "POD_NAME", "POD_NAMESPACE", "CONTAINER_NAME"}
for _, envVar := range envVars {
    if value := os.Getenv(envVar); value != "" {
        _, _ = fmt.Fprintf(w, "%s: %s\n", envVar, value)
    }
}

Impact

  • Severity: MEDIUM
  • Exposure of bearer tokens, API keys in Authorization headers
  • Potential exposure of secrets in environment variables
  • Risk if responses are logged, cached, or exposed via proxy/CDN
  • Information leakage for reconnaissance attacks

Scenarios

  1. Authorization Header Leakage: Bearer tokens echoed to attackers
  2. Environment Variable Exposure: Database credentials, API keys in env vars
  3. Log/Monitoring Exposure: Sensitive data captured in application logs

Recommended Fix

Option 1: Redact Sensitive Headers

func (h helloWorldhandler) printHeaders(w http.ResponseWriter, info requestInfo) {
    _, _ = fmt.Fprintf(w, "=== REQUEST HEADERS ===\n")
    
    // Highlight important headers first (redact Authorization)
    importantHeaders := []string{"Content-Type", "Content-Length", "Authorization", "Accept", "Accept-Encoding"}
    for _, headerName := range importantHeaders {
        if value := info.Headers.Get(headerName); value != "" {
            // Redact sensitive headers
            if headerName == "Authorization" {
                _, _ = fmt.Fprintf(w, "* %-15s: [REDACTED]\n", headerName)
            } else {
                _, _ = fmt.Fprintf(w, "* %-15s: %s\n", headerName, value)
            }
        }
    }
    
    _, _ = fmt.Fprintf(w, "\nAll Headers:\n")
    for name, values := range info.Headers {
        for _, value := range values {
            // Redact in full listing too
            if strings.ToLower(name) == "authorization" || strings.ToLower(name) == "cookie" {
                _, _ = fmt.Fprintf(w, "  %-20s: [REDACTED]\n", name)
            } else {
                _, _ = fmt.Fprintf(w, "  %-20s: %s\n", name, value)
            }
        }
    }
    _, _ = fmt.Fprintf(w, "\n")
}

Option 2: Whitelist Safe Environment Variables

// Only print safe, non-sensitive environment variables
safeEnvVars := []string{"HOSTNAME", "POD_NAME", "POD_NAMESPACE"}
for _, envVar := range safeEnvVars {
    if value := os.Getenv(envVar); value != "" {
        _, _ = fmt.Fprintf(w, "%s: %s\n", envVar, value)
    }
}

Option 3: Add Prominent Warning

Update README.md and add runtime warning:

log.Println("WARNING: This server echoes sensitive request data. Do NOT use in production with real credentials.")

Documentation Updates

Add to README.md:

## Security Warning

⚠️ **Do not use in production with sensitive data**

This server echoes ALL request information including:
- Authorization headers (bearer tokens, API keys)
- All HTTP headers
- Request bodies
- Environment variables

Use only in isolated development/testing environments.

Testing

  • Send requests with Authorization headers
  • Verify sensitive values are redacted
  • Check environment variable output is safe
  • Review logs for sensitive data leakage

Priority

Medium - Security issue, but this is by design as a diagnostic tool. Should be documented clearly.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions