Skip to content

forwardauth: Skip copying missing response headers#6608

Merged
mholt merged 1 commit intomasterfrom
forward-auth-empty-headers
Nov 4, 2024
Merged

forwardauth: Skip copying missing response headers#6608
mholt merged 1 commit intomasterfrom
forward-auth-empty-headers

Conversation

@francislavoie
Copy link
Member

@francislavoie francislavoie commented Oct 6, 2024

Reported here: https://caddy.community/t/copy-header-copying-empty-headers-with-authelia/25885, but I think it has been mentioned elsewhere before as well. Fixes #6610

Basically, because we use ReplaceKnown in the request_header handler for placeholders, the copy_header shortcut for forward_auth would cause the request headers to be set to the placeholder string itself instead of skipping, when the response was missing that header.

The fix is to use a not vars matcher to check that the response header placeholder has a non-empty value first.

Unfortunately this produces some super verbose JSON config, but the behaviour will be more correct.

@francislavoie francislavoie force-pushed the forward-auth-empty-headers branch from 8bce42e to 222a84f Compare October 10, 2024 20:54
Copy link
Member

@mholt mholt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, thanks for maintaining this!

@mholt mholt merged commit 05cfb12 into master Nov 4, 2024
@mholt mholt deleted the forward-auth-empty-headers branch November 4, 2024 21:58
mohammed90 pushed a commit to cedricziel/caddy that referenced this pull request Aug 29, 2025
NucleiAv added a commit to NucleiAv/caddy that referenced this pull request Mar 4, 2026
…lied headers

When using copy_headers in a forward_auth block, client-supplied headers with
the same names were not being removed before being forwarded to the backend.

This happens because PR caddyserver#6608 added a MatchNot guard that skips the Set
operation when the auth service does not return a given header. That guard
prevents setting headers to empty strings, which is the correct behavior,
but it also means a client can send X-User-Id: admin in their request and
if the auth service validates the token without returning X-User-Id, Caddy
skips the Set and the client value passes through unchanged to the backend.

The fix adds an unconditional delete route for each copy_headers entry,
placed just before the existing conditional set route. The delete always runs
regardless of what the auth service returns. The conditional set still only
runs when the auth service provides that header.

The end result is:
  - Client-supplied headers are always removed
  - When the auth service returns the header, the backend gets that value
  - When the auth service does not return the header, the backend sees nothing

Existing behavior is unchanged for any deployment where the auth service
returns all of the configured copy_headers entries.

Fixes GHSA-7r4p-vjf4-gxv4
NucleiAv added a commit to NucleiAv/caddy that referenced this pull request Mar 4, 2026
…lied headers

When using copy_headers in a forward_auth block, client-supplied headers with
the same names were not being removed before being forwarded to the backend.

This happens because PR caddyserver#6608 added a MatchNot guard that skips the Set
operation when the auth service does not return a given header. That guard
prevents setting headers to empty strings, which is the correct behavior,
but it also means a client can send X-User-Id: admin in their request and
if the auth service validates the token without returning X-User-Id, Caddy
skips the Set and the client value passes through unchanged to the backend.

The fix adds an unconditional delete route for each copy_headers entry,
placed just before the existing conditional set route. The delete always runs
regardless of what the auth service returns. The conditional set still only
runs when the auth service provides that header.

The end result is:
  - Client-supplied headers are always removed
  - When the auth service returns the header, the backend gets that value
  - When the auth service does not return the header, the backend sees nothing

Existing behavior is unchanged for any deployment where the auth service
returns all of the configured copy_headers entries.

Fixes GHSA-7r4p-vjf4-gxv4
francislavoie pushed a commit that referenced this pull request Mar 4, 2026
…headers (Fixes GHSA-7r4p-vjf4-gxv4) (#7545)

When using copy_headers in a forward_auth block, client-supplied headers with
the same names were not being removed before being forwarded to the backend.

This happens because PR #6608 added a MatchNot guard that skips the Set
operation when the auth service does not return a given header. That guard
prevents setting headers to empty strings, which is the correct behavior,
but it also means a client can send X-User-Id: admin in their request and
if the auth service validates the token without returning X-User-Id, Caddy
skips the Set and the client value passes through unchanged to the backend.

The fix adds an unconditional delete route for each copy_headers entry,
placed just before the existing conditional set route. The delete always runs
regardless of what the auth service returns. The conditional set still only
runs when the auth service provides that header.

The end result is:
  - Client-supplied headers are always removed
  - When the auth service returns the header, the backend gets that value
  - When the auth service does not return the header, the backend sees nothing

Existing behavior is unchanged for any deployment where the auth service
returns all of the configured copy_headers entries.

Fixes GHSA-7r4p-vjf4-gxv4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug 🐞 Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ForwardAuth with copy_headers leaves template code in header if auth backend doesn't set that header

2 participants