JSON requests from my API are blocked by the "Block Invalid JSON Contents" rule; why?
Short answer
Block Invalid JSON Contents is triggered when a request body whose Content-Type header declares JSON (…/json or …+json) cannot be parsed as JSON. It is a 24-point structural violation; at every protection level, it reaches the blocking threshold on its own. It is triggered if the body is not valid JSON (a trailing comma, a comment line, single quotes, line-by-line JSON), if it is sent compressed with Content-Encoding (the WAF does not decompress the body) or if the Content-Type declares JSON by mistake. The rule is off by default in Any Paths; it comes on in the page types in which Analysis & Learning saw a JSON body, in Any paths rebuilt with Sync with Default WAF Rules at the Aggressive level and in the JSON parts added with WEB-CLI. The headers and the body on the Request & Location tab of the record are examined; the client is fixed, or the box is unchecked in the JSON common rule of the page type the request matches. While the box is off, a body that cannot be parsed is not blocked; it goes through signature scanning as raw content. The often-confused Block All JSON Contents, on the other hand, blocks every JSON body, valid or invalid.
Problem: The API's JSON Requests Are Blocked
The requests sent by the API client receive the blocking response (default status code 418); on the Attacks tab of the Event Logs record, Attack Name = Block Invalid JSON Contents, Attack area = JSON appears. Whether the body is invalid and whether the request will be processed as JSON are determined according to the Content-Type header.
Possible Causes
| Cause | How to tell it apart |
|---|---|
The body is not JSON conforming to RFC 8259: a trailing comma ({"a":1,}), a comment line, a single-quoted or unquoted key, multiple root values (line-by-line JSON) | Request & Location → Body (the body is recorded if it is below the Max. Body Size to Log(kB) limit; default 2 kB) |
The body is sent compressed with Content-Encoding; the WAF does not decompress the request body and the compressed byte sequence cannot be parsed as JSON | HTTP Headers → content-encoding (e.g. gzip) |
Content-Type declares JSON but the body is in another format (form data, plain text) | HTTP Headers → content-type; Body |
| The box is on at this endpoint: the rule the request matches is a page type created by Analysis & Learning, Any Paths set up with Sync with Default WAF Rules at the Aggressive level, or a JSON part added with WEB-CLI | Attacks → Corresponding Rule; the Block Invalid JSON Contents row on the JSON tab of the rule |
Definitive rules:
- The requests processed as JSON are the requests whose
Content-Typevalue fits the…/json(e.g.application/json,application/json; charset=utf-8,text/json) or…+json(e.g.application/vnd.api+json,application/problem+json) form, case-insensitively. Other types do not enter the JSON inspections. - If the body did not fit in the inspection buffer, JSON parsing is not done at all; the record is not Block Invalid JSON Contents but Block Unparsed Contents (Large POST requests are blocked or cut off; why?).
- The rule is evaluated in Monitor Mode and Blocking Mode and blocks in Blocking mode; it is not scored in Learning Mode. If Structure Checks on the Checks card is off, it is not applied (on by default).
- While the box is off, a body that cannot be parsed is not blocked; it goes through signature scanning as raw content with the OWASP Check setting of the Raw tab. While the box is on, the inspection ends at this point, since 24 points reach the blocking threshold.
- In the interface, the form opened with Add Common Rule for JSON comes filled with the JSON values of Any paths; if the box is off in Any paths, it is also off in the new common rule. The
waf rule-parts add … loc jsoncommand in WEB-CLI, on the other hand, writes the Block all JSON contents and Block invalid JSON contents fields as on when they are not specified (loc json fields). - Block All JSON Contents (Structure Policies category) blocks the JSON body without parsing it. If this record is seen, the rule has been set up so as not to accept a JSON body. An analysis applied with Ignore Old Rules = Create New Rules turns this box on in Any paths; in the page types in which a JSON body was seen during the learning period (in the Page independent policy, in Any paths itself), the box stays off (New pages are blocked after I released a new version; what should I do?).
Where Is It Monitored?
| Screen | Path | What it shows |
|---|---|---|
| Event Logs | Left Monitor Panel → WAF-Protected vServices → vService → Event Logs | On the Attacks tab, Attack name, Corresponding rule, Learning suggestion (Block invalid JSON contents will be disabled); on the Request & Location tab, HTTP headers, Body, Matching path rules |
| Page Types → JSON tab | WAF Management → mode card of the host group → N page types → rule | The state of the box; if the value is inherited, Rule source |
Solution: Four Methods
If the body is really malformed, the correction is made on the client. If the endpoint knowingly accepts an invalid or compressed body, the box is unchecked only in that page type.
| Your situation | Suitable method |
|---|---|
The client sends invalid JSON, a wrong Content-Type or a compressed body | Method 1: Fixing the client |
| The rule is unnecessary at this endpoint; it will be removed from the rule screen | Method 2: Unchecking the box in the page type |
| The rule is unnecessary at this endpoint; it will be removed from the record | Method 3: Allow from Event Logs |
| The setting will be made from the command line | Method 4: WEB-CLI |
| The record is Block All JSON Contents | Can I forbid JSON or XML bodies entirely on a page (Block All JSON Contents / Block All XML Contents)? |
Method 1: Fixing the Client Recommended
- How it works The headers and the body in the record are examined; the client is fixed so that it sends valid, uncompressed JSON and declares the
Content-Typeconsistently with the body. The WAF setting does not change; the inspection is preserved. - Where it is opened Left Monitor Panel → WAF-Protected vServices → vService → Event Logs → record → Request & Location
- Requirement View permission in the WAF area; a change in the client application
- vService type HTTP
Step-by-Step Configuration
In the Left Monitor Panel, the WAF-Protected vServices category is selected, the vService is clicked and the Event Logs tab is opened.
On the server filter tab, the Request ID in the response the client received is written in the Request Unique ID field, or Date Range is selected so as to cover the time of the event.
Save & Get Logs is clicked.
The row is clicked and the Request & Location tab is selected in the preview. The HTTP Headers and Body fields are opened with the eye icon in their titles; content-type, content-encoding and the format of the body are read.
On the client side, the body is produced as valid JSON, the request body is sent without compression and Content-Type declares the real format of the body (e.g. application/x-www-form-urlencoded for form data). There is no change to be made on the WAF side.
Verification
The corrected request is sent.
Command: curl -s -o /dev/null -w "%{http_code}" -H "Content-Type: application/json" -d '{"a":1}' https://api.example.com/v1/orders
The response code of the Backend Service (not 418)Method 2: Unchecking the Box in the Page Type
- How it works The Block Invalid JSON Contents check is removed in the JSON common rule of the page type the request matches; the other page types and Any paths do not change.
- Where it is opened Left Monitor Panel → WAF-Protected vServices → vService → WAF Management → N page types → rule → JSON tab
- Requirement Modify permission in the WAF area
- vService type HTTP
Step-by-Step Configuration
In the Left Monitor Panel, WAF-Protected vServices is selected, the vService is clicked and the WAF Management tab is opened. The N page types link on the mode card of the host group the request falls into is clicked (accessing the screen).
The row of the rule written in Corresponding Rule in the record is clicked; the detail panel opens.
JSON is clicked in the tab strip of the panel. If the Rule source row appears, the value is being inherited from another rule; the change is made in that rule or by adding a common rule of its own to this rule (inheritance).
Edit Common Rule for JSON (if the rule has a JSON common rule of its own) or Add Common Rule for JSON is clicked (Add common rule for JSON screen).
The Block Invalid JSON Contents check is removed. If the endpoint accepts a JSON body, it is verified that Block All JSON Contents is also unchecked.
Edit in the form (or Add for a new common rule) is clicked; the change is applied without a separate deployment step. In a cluster setup, the change is also sent to the peer device with the default auto-sync; if Manual Sync Mode is on, it is sent with Synchronize.
Verification
The Block Invalid JSON Contents row on the JSON tab of the rule is examined.
-✓, and the fields that are off with -.Method 3: Allow from Event Logs
- How it works The Block Invalid JSON Contents attack in the record is taught; the Learning Suggestion row writes
Block invalid JSON contents will be disabled, and the teaching unchecks the box in the matched rule. The result is the same as with Method 2. - Where it is opened Left Monitor Panel → WAF-Protected vServices → vService → Event Logs → record → Attacks
- Requirement Modify permission in the WAF area; the record being present in Event Logs (host group in Monitor or Blocking mode)
- vService type HTTP
Step-by-Step Configuration
In Event Logs, the record is fetched with steps 1–3 of Method 1, the row is clicked and the Attacks tab is selected in the preview.
In the attack table, the box of the Block Invalid JSON Contents row is checked.
The button above the table is clicked. The button carries the name Allow in a blocked record and Teach in a record written in Monitor mode (Allow / Teach).
Yes is clicked in the Are you sure? question; the change is applied without a separate deployment step. In a cluster setup, the change is also sent to the peer device with the default auto-sync; if Manual Sync Mode is on, it is sent with Synchronize. Details: Which rule changes in the background when I Allow / Teach (Learning Suggestion)?
Verification
The Attacks column of the taught record in Event Logs is examined.
First number 0; row greenMethod 4: WEB-CLI
- How it works In the JSON common part of the rule, the
jsonBlockInvalidfield is set tofalsewith the WEB-CLIwaf rule-parts updatecommand. - Where it is opened WEB-CLI →
waf fw-rules·waf rule-parts - Requirement WEB-CLI access and modify permission in the WAF area; the rule having a JSON common part of its own
- vService type HTTP
Step-by-Step Configuration
waf fw-rules list poolId <vService> hostGroupId <group>The ID of the default host group is defaultHost, and the ID of the Any paths rule is wr-default.
waf rule-parts list poolId <vService> hostGroupId <group> ruleId <rule>The part whose region is json and that carries no argument name is the JSON common part. If it is not in the list, the rule is inheriting the JSON settings; the change is made in the rule it inherits from.
waf rule-parts update poolId <vService> hostGroupId <group> ruleId <rule> id <part> --jsonBlockInvalid falseVerification
The part is displayed again.
Command: waf rule-parts show poolId <vService> hostGroupId <group> ruleId <rule> <part>
jsonBlockInvalid falseCommon Mistakes
- Confusing the two rules. Block Invalid JSON Contents blocks only a body that cannot be parsed, while Block All JSON Contents blocks every JSON body, valid or invalid.
- Looking for the box in Any paths. It is off by default in Any paths; the change is made to the rule written in Corresponding Rule in the record.
- Overlooking a compressed request body. The WAF does not decompress the request body; a JSON request that carries
Content-Encodingcannot be parsed. - Not specifying the fields when adding a JSON part with WEB-CLI.
waf rule-parts add … loc jsonwrites the Block All JSON Contents and Block Invalid JSON Contents fields as on; at an endpoint that accepts JSON,--jsonBlockAll falseis written. - Confusing a buffer-related record with this rule. If the body did not fit in the buffer, the record is Block Unparsed Contents (Large POST requests are blocked or cut off; why?).
How it is done in the documentation
Related questions
- Can I block malformed (unparseable) JSON / XML / form bodies?
- Can I forbid JSON or XML bodies entirely on a page (Block All JSON Contents / Block All XML Contents)?
- What does the Raw tab inspect; what happens to content that cannot be parsed?
- Can I apply schema-like checks (key list, depth, length) to JSON-bodied API requests?
