Skip to content

IP whitelist path unconditionally strips Authorization and X-API-TOKEN headers, ignoring removeHeadersOnSuccess #20

@mrohlof-protofy

Description

@mrohlof-protofy

Version: v0.1.4

Summary

When a request's source IP matches whitelistIPs, the plugin deletes both Authorization and X-API-TOKEN headers from the request before forwarding to the backend, regardless of how removeHeadersOnSuccess is configured. This silently breaks backends that use the Authorization header for their own purposes (e.g. bearer-token auth to an upstream API).

Where

plugin.go lines 536-543:

  if sliceIp(*ipAddress, ka.whitelistIPs) {                                                                            
      logInfo.Printf(...)                                                                                                                         
      req.Header.Del(ka.authenticationHeaderName)  // X-API-TOKEN
      req.Header.Del(ka.bearerHeaderName)          // Authorization                                                                               
      ka.next.ServeHTTP(rw, req)                                                                                       
      return                                                                                                                                      
  }     

The removeHeadersOnSuccess flag is checked on the two other success paths (lines 489 and 511) but not on the IP-whitelist path.

Expected behavior

Headers should only be removed when removeHeadersOnSuccess == true. This is consistent with how the flag guards the header removal on the X-API-TOKEN and Authorization token-match paths.

Actual behavior

On IP-whitelist match, both headers are always removed even if removeHeadersOnSuccess: false. The user has no way to preserve their own
Authorization header for downstream use when relying on IP whitelisting.

Reproducer

Minimal Middleware config:

apiVersion: traefik.io/v1alpha1                                                                                                                 
kind: Middleware                                                                                                     
metadata:                           
  name: api-key-auth
spec:                                                                                                                                           
  plugin:
    traefik-api-token-middleware:                                                                                                               
      authenticationHeaderName: X-API-TOKEN                                                                          
      tokens: ["secret"]                                                                                                                        
      whitelistIps: ["10.0.0.0/8"]
      removeHeadersOnSuccess: false                                                                                                             

Request from an IP in the whitelist with an unrelated bearer token:

GET /protected                                                                                                                                  
Host: example.com                                                                                                                               
Authorization: Bearer <some-backend-auth-token>

The backend receives the request without Authorization, even though removeHeadersOnSuccess is false.

Suggested fix

Guard the IP-whitelist header deletion with removeHeadersOnSuccess, matching the pattern used on lines 489 and 511:

if sliceIp(*ipAddress, ka.whitelistIPs) {                                                                                                       
    logInfo.Printf(...)                                                                                              
    if ka.removeHeadersOnSuccess {                                                                                                              
        req.Header.Del(ka.authenticationHeaderName)
        req.Header.Del(ka.bearerHeaderName)                                                                                                     
    }                                                                                                                                           
    ka.next.ServeHTTP(rw, req)      
    return                                                                                                                                      
}

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