Skip to content

fix(chaitin-waf): use trusted client IP source for WAF backend#13339

Open
shreemaan-abhishek wants to merge 2 commits intoapache:masterfrom
shreemaan-abhishek:fix/chaitin-waf-x-forwarded-for-spoofing
Open

fix(chaitin-waf): use trusted client IP source for WAF backend#13339
shreemaan-abhishek wants to merge 2 commits intoapache:masterfrom
shreemaan-abhishek:fix/chaitin-waf-x-forwarded-for-spoofing

Conversation

@shreemaan-abhishek
Copy link
Copy Markdown
Contributor

Description

The chaitin-waf plugin populates the client_ip field sent to the Chaitin WAF backend by reading ctx.var.http_x_forwarded_for directly when config.real_client_ip = true (the default). This bypasses nginx's real_ip module: any external client can supply an arbitrary X-Forwarded-For header and have it forwarded verbatim to the WAF, making attribution and policy decisions on that field attacker-controllable.

This change replaces the raw-header read with core.request.get_remote_client_ip(ctx) (which returns $remote_addr after real_ip processing) when real_client_ip is enabled, and core.request.get_ip(ctx) (direct TCP peer, ignoring realip rewrites) when disabled. The toggle's intent is preserved:

  • real_client_ip = true (default): forwards the realip-resolved client IP — the forwarded header is honored only when the request comes from a trusted proxy listed in set_real_ip_from. Spoofed headers from untrusted sources are ignored.
  • real_client_ip = false: forwards the actual TCP peer address.

This applies the same fix shape used for wolf-rbac in #13329.

An info-level log line records the chosen client_ip for auditability and to anchor the regression tests.

Which issue(s) this PR fixes:

Fixes #

Checklist

  • I have explained the need for this PR and the problem it solves
  • I have explained the changes or the new features added to this PR
  • I have added tests corresponding to this change
  • I have updated the documentation to reflect this change
  • I have verified that this change is backward compatible

The plugin populated `client_ip` sent to the Chaitin WAF backend by
reading `ctx.var.http_x_forwarded_for` directly when `real_client_ip`
is enabled, bypassing nginx's `real_ip` module. Any external client
could supply an arbitrary `X-Forwarded-For` header and have it
forwarded to the WAF unchecked.

Replace the raw-header read with `core.request.get_remote_client_ip`
(realip-aware) when `real_client_ip = true`, and `core.request.get_ip`
(direct TCP peer) when false. This applies the same fix shape used
for wolf-rbac in apache#13329.
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. bug Something isn't working labels May 7, 2026
`get_conf` merged `real_client_ip` with `or`, which silently fell
back to the default `true` whenever the user explicitly set `false`,
making the toggle ineffective. Replace with an explicit nil check so
both `true` and `false` overrides are honored.

Also tighten the existing `real_client_ip = false` test to assert the
chosen `client_ip` (not just the response), and add a regression case
that verifies the `false` branch wins over `set_real_ip_from`-trusted
`X-Forwarded-For` rewrites.
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant