Stripping Inbound x-amzn-waf-* Headers Before Trusting Them
Overview
Domain expertise for the mandatory safety companion to any AWS WAF header forwarding: a block rule
that rejects inbound requests already carrying an x-amzn-waf-* header, so an attacker cannot
forge the signal the origin trusts. Covers why the gap exists (AWS WAF does not strip pre-existing
x-amzn-waf-* headers before inserting its own) and the rule placement.
Does not cover the forwarding workflows themselves; this is their required companion. The confidence-signal, interpolation, and client-IP references all point here.
Execute commands using the AWS MCP server when connected (sandboxed execution, audit logging, observability). Fall back to the AWS CLI otherwise.
Table of Contents
- Overview
- Workflow
- Why the spoofing gap exists
- A mandatory companion, not optional hardening
- Troubleshooting
- Procedure
- Security Considerations
- Additional Resources
Workflow
To add the inbound-header-stripping rule end to end, follow the procedure exactly. See the Procedure section below.
The procedure covers:
- Adding a block rule matching any inbound
x-amzn-waf-*header - Placing it before the forwarding rules
- Confirming and surfacing the console link
Why the spoofing gap exists
AWS WAF custom request handling does not strip a pre-existing x-amzn-waf-* header before inserting
its own. A request that arrives already carrying one passes that forged value to the origin, so an
origin trusting x-amzn-waf-bot-category:verified, a spoofed confidence value, or a spoofed client
IP is bypassable.
Constraints:
- You MUST add a block rule that rejects any inbound request already carrying an
x-amzn-waf-*header - You MUST place that rule at a lower priority number than the forwarding rules, so it runs first and only AWS-WAF-set values reach the origin
A mandatory companion, not optional hardening
The vulnerability is the absence of a rule, not a misconfiguration that throws an error, so it is easy to ship header forwarding without it.
Constraints:
- You MUST treat this rule as a mandatory companion whenever the skill recommends header forwarding, not an optional hardening step
- You SHOULD confirm the stripping rule is present before declaring any forwarding workflow complete
Troubleshooting
The origin trusts a forged signal
No stripping rule is present, or it runs after the forwarding rules. Add it before them (Why the spoofing gap exists).
Legitimate requests are blocked by the strip rule
A legitimate upstream is setting an x-amzn-waf-* header. That is unusual; confirm the upstream and
narrow the match if a specific known header must pass, but default to blocking all inbound
x-amzn-waf-*.
Procedure
Overview
This procedure adds a block rule for inbound x-amzn-waf-* headers before the forwarding rules,
then surfaces the console link.
Parameters
- web_acl_name, web_acl_id, scope (required): Identify the web ACL.
Constraints for parameter acquisition:
- You MUST ask for all required parameters upfront in a single prompt
- You MUST confirm which forwarding rules exist so the strip rule is placed before them
Steps
1. Verify dependencies
Constraints:
- You MUST confirm credentials with
aws sts get-caller-identity - You MUST identify the priority numbers of the forwarding rules
2. Add the inbound strip rule
Constraints:
You MUST add a block rule matching any request that carries an
x-amzn-waf-*header (a header match on thex-amzn-waf-prefix), at a lower priority number than the forwarding rulesYou MUST fetch the current
LockTokenbeforeupdate-web-acland pass the full rule setYou MUST preserve the web ACL's existing
DefaultActionfrom theget-web-aclresponse and pass it back as{default_action}; do not assumeAllow={}, since that would silently open all unmatched traffic on a web ACL whose default action isBlock. For example, a Block rule whoseByteMatchStatementmatches thex-amzn-waf-prefix on header keys:aws wafv2 get-web-acl --name {web_acl_name} --scope {scope} --id {web_acl_id} --region {region} aws wafv2 update-web-acl --name {web_acl_name} --scope {scope} --id {web_acl_id} \ --lock-token {lock_token} --default-action {default_action} \ --rules '[{"Name":"StripInboundWafHeaders","Priority":0,"Action":{"Block":{}},"Statement":{"ByteMatchStatement":{"SearchString":"x-amzn-waf-","PositionalConstraint":"STARTS_WITH","FieldToMatch":{"Headers":{"MatchPattern":{"All":{}},"MatchScope":"KEY","OversizeHandling":"MATCH"}},"TextTransformations":[{"Priority":0,"Type":"LOWERCASE"}]}},"VisibilityConfig":{"SampledRequestsEnabled":true,"CloudWatchMetricsEnabled":true,"MetricName":"StripInboundWafHeaders"}}]' \ --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName={web_acl_name} \ --region {region}
3. Confirm and surface the console link
Constraints:
You MUST confirm the strip rule runs before the forwarding rules
You MUST present the web ACL console link and tell the customer to confirm the rule order:
https://us-east-1.console.aws.amazon.com/wafv2/homev2/web-acls?region={region}
Example
Example input
{
"web_acl_name": "example-webacl",
"web_acl_id": "abc",
"scope": "REGIONAL"
}Example output
Added a Block rule rejecting any inbound request carrying an x-amzn-waf-* header, at priority 0 (before the forwarding rules).
Open the web ACL and confirm the strip rule runs first:
https://us-east-1.console.aws.amazon.com/wafv2/homev2/web-acls?region=us-east-1Troubleshooting
The origin trusts a forged value
The strip rule is missing or runs after the forwarding rules. Place it before them (Step 2).
Security Considerations
This procedure modifies a security control, so misconfiguration directly weakens the application's defenses.
- Least-privilege IAM. You MUST grant only the specific
wafv2:actions a task needs (for examplewafv2:GetWebACLandwafv2:UpdateWebACL) rather thanwafv2:*or theAWSWAFFullAccessmanaged policy. - Ephemeral credentials. You MUST use IAM roles with temporary credentials (such as an EC2 instance profile, SSO session, or
aws sts assume-role) rather than long-lived IAM user access keys when running these WAF CLI commands. - Monitor configuration changes. You SHOULD enable AWS CloudTrail on
wafv2management events and set CloudWatch alarms on critical web ACL configuration changes (such asDeleteWebACLandUpdateWebACLrule removals) and on the web ACL'sBlockedRequestsandCountedRequestsmetrics, so rule changes and sudden spikes in blocked or counted traffic are detected. - Header-spoofing risk. Any
x-amzn-waf-*signal forwarded to the origin can be forged inbound. You MUST add the inbound-header-stripping rule whenever a signal or client IP is forwarded (see stripping-inbound-waf-headers-before-trusting-them); without it the origin trusts a spoofable value.