I tried the new AWS WAF feature "Parsed Text Transformation" using the CLI

I tried the new AWS WAF feature "Parsed Text Transformation" using the CLI

In July 2026, I configured the pre-parse text transformation newly added to AWS WAF using the AWS CLI. Using the Count action and WAF labels for verification, I will confirm through WAF logs how semicolon-delimited and URL-encoded query strings are reflected in rule matching.
2026.07.31

This page has been translated by machine translation. View original

Introduction

With the update on July 29, 2026, pre-parse text transformations became available in AWS WAF.

https://aws.amazon.com/about-aws/whats-new/2026/07/aws-waf/

Pre-parse text transformations are a feature that inserts normalization before parsing query strings into key-value pairs. Traditional text transformations operate on parsed values when inspecting query arguments. Therefore, the handling of delimiters cannot be reflected in the parse results. The official documentation states that pre-parse text transformations can be applied to statements that inspect SingleQueryArgument or AllQueryArguments.

https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-preparse-transformation.html

With rules without transformations, neither semicolon-delimited nor URL-encoded semicolon-delimited queries matched. The results after configuring pre-parse text transformations are as follows.

Query delimiter Applied pre-parse text transformation (Type)
Semicolon-delimited REPLACE_SEMICOLONS_WITH_AMPERSANDS
URL-encoded semicolon-delimited URL_DECODEREPLACE_SEMICOLONS_WITH_AMPERSANDS

Validation Details

Configuring Count Action and Rule Labels

The validation environment is as follows.

Item Value
AWS CLI 2.36.11
Region ap-northeast-1
Web ACL Scope REGIONAL
Backend Fixed-response ALB
Log destination CloudWatch Logs

To prevent the block action from interrupting evaluation of subsequent rules, validation rules were set to the Count action, and validation WAF labels were assigned to each rule. WAF log records and HTTP requests were correlated using the query string as a key. Since Count does not block requests, the basis for judgment was labels and nonTerminatingMatchingRules rather than HTTP status. The test Web ACL contained no blocking rules, only these validation Count rules.

# Retrieve LockToken
LOCK_TOKEN=$(aws wafv2 get-web-acl \
  --name preparse-test-webacl \
  --id 11111111-2222-3333-4444-55555555aaaa \
  --scope REGIONAL \
  --region ap-northeast-1 \
  --query LockToken --output text)

# Configure Count rules and labels
aws wafv2 update-web-acl \
  --name preparse-test-webacl \
  --id 11111111-2222-3333-4444-55555555aaaa \
  --scope REGIONAL \
  --default-action '{"Allow":{}}' \
  --lock-token "$LOCK_TOKEN" \
  --region ap-northeast-1 \
  --visibility-config 'SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=preparse-test-webacl' \
  --rules file://rules.json

# Verify saved configuration
aws wafv2 get-web-acl \
  --name preparse-test-webacl \
  --id 11111111-2222-3333-4444-55555555aaaa \
  --scope REGIONAL \
  --region ap-northeast-1

For comparison, two control rules without pre-parse transformations but with the same matching conditions (ControlNoPreparsePlain, ControlNoPreparseEncoded) were also added. The following is an excerpt from the rule configuration passed to --rules, showing the two rules with pre-parse transformations.

[
  {
    "Name": "PreparseSemicolon",
    "Priority": 2,
    "Statement": {
      "ByteMatchStatement": {
        "SearchString": "cHJlcGFyc2UtcGxhaW4=",
        "FieldToMatch": { "SingleQueryArgument": { "Name": "target_plain" } },
        "TextTransformations": [ { "Priority": 0, "Type": "NONE" } ],
        "PositionalConstraint": "EXACTLY",
        "PreParseTextTransformations": [
          { "Priority": 0, "Type": "REPLACE_SEMICOLONS_WITH_AMPERSANDS" }
        ]
      }
    },
    "Action": { "Count": {} },
    "RuleLabels": [ { "Name": "test:preparse-semicolon" } ]
  },
  {
    "Name": "PreparseUrlDecodeSemicolon",
    "Priority": 4,
    "Statement": {
      "ByteMatchStatement": {
        "SearchString": "cHJlcGFyc2UtZW5jb2RlZA==",
        "FieldToMatch": { "SingleQueryArgument": { "Name": "target_encoded" } },
        "TextTransformations": [ { "Priority": 0, "Type": "NONE" } ],
        "PositionalConstraint": "EXACTLY",
        "PreParseTextTransformations": [
          { "Priority": 0, "Type": "URL_DECODE" },
          { "Priority": 1, "Type": "REPLACE_SEMICOLONS_WITH_AMPERSANDS" }
        ]
      }
    },
    "Action": { "Count": {} },
    "RuleLabels": [ { "Name": "test:preparse-url-decode-semicolon" } ]
  }
]

The SearchString values are Base64-encoded strings. cHJlcGFyc2UtcGxhaW4= corresponds to preparse-plain, and cHJlcGFyc2UtZW5jb2RlZA== corresponds to preparse-encoded. The VisibilityConfig for each rule is omitted from the excerpt. After the update, the get-web-acl output confirmed that PreParseTextTransformations and RuleLabels were saved correctly.

Verifying Semicolon-Delimited Queries

Requests with semicolon-delimited and ampersand-delimited queries were sent to the rule configured with REPLACE_SEMICOLONS_WITH_AMPERSANDS.

Case Request query HTTP result Labels confirmed in WAF log Non-terminating matching rules
Semicolon-delimited q=safe;target_plain=preparse-plain 200 / ALLOW test:preparse-semicolon PreparseSemicolon
Standard ampersand-delimited (plain) q=safe&target_plain=preparse-plain 200 / ALLOW test:control-no-preparse-plain, test:preparse-semicolon ControlNoPreparsePlain, PreparseSemicolon

For semicolon-delimited queries, only the rule with pre-parse transformation matched, and no control rule label was assigned. For ampersand-delimited queries, both matched, and the labels show that the presence or absence of the transformation made the difference in results.

The following is an excerpt from the WAF log corresponding to the semicolon-delimited request. The labels values include a prefix containing the Web ACL name.

{
  "action": "ALLOW",
  "terminatingRuleId": "Default_Action",
  "nonTerminatingMatchingRules": [
    { "ruleId": "PreparseSemicolon", "action": "COUNT", "ruleMatchDetails": [] }
  ],
  "httpRequest": { "args": "q=safe;target_plain=preparse-plain" },
  "labels": [
    { "name": "awswaf:123456789012:webacl:preparse-test-webacl:test:preparse-semicolon" }
  ]
}

Verifying URL-Encoded Semicolons

Requests for the following two cases were sent to the rule chaining URL_DECODE and REPLACE_SEMICOLONS_WITH_AMPERSANDS.

Case Request query HTTP result Labels confirmed in WAF log Non-terminating matching rules
URL-encoded semicolon-delimited q=safe%3Btarget_encoded=preparse-encoded 200 / ALLOW test:preparse-url-decode-semicolon PreparseUrlDecodeSemicolon
Standard ampersand-delimited (encoded) q=safe&target_encoded=preparse-encoded 200 / ALLOW test:control-no-preparse-encoded, test:preparse-url-decode-semicolon ControlNoPreparseEncoded, PreparseUrlDecodeSemicolon

For requests containing URL-encoded semicolons, only the rule chaining decode and replacement matched, and no control rule label was assigned. For ampersand-delimited queries, both rules matched.

Summary

If you are currently combining regular expressions or multiple rules to handle differences in query string delimiters and encoding, using the newly added pre-parse text transformations may allow for simpler management. Each pre-parse text transformation adds 10 WCUs, but as long as the Web ACL total remains at or below the default allocation of 1,500 WCUs, it can be used at no additional charge.

Share this article

AWSのお困り事はクラスメソッドへ

Related articles