Can I block malformed (unparseable) JSON / XML / form bodies?
Short answer
Yes. While the Block Invalid JSON Contents, Block Invalid XML Contents and Block Invalid Form Contents boxes in the common rule of the JSON, Xml and Form tabs are checked, a body that declares with Content-Type that it is JSON, XML or form and cannot be parsed produces a 24-point violation in the Content Integrity category. While the box is not checked, a malformed body is not blocked; it goes through the signature scanning of the Raw tab as raw content. In the Any paths default, the box is checked for Xml and unchecked for JSON and Form; the common rule form opened in the page type comes filled with these values. In Form, the main subject of the inspection is a malformed multipart structure; since a file field left empty by the browser (filename="") also counts as a parsing error, forms with an optional file field also produce a violation when they are sent without a file being selected. The inspection runs in the Blocking and Monitor modes and depends on the Structure Checks switch in the Checks window.
Problem: Malformed Bodies Reach the Application
Bodies that declare Content-Type: application/json but are not valid JSON, or multipart bodies with broken boundaries, can be used to bypass body inspections or to produce errors in the parser of the application. Bodies that do not match the type they declare are wanted to be rejected before they reach the application.
Solution: Two Methods
The two methods set the same box; one of them is selected.
| Your situation | Suitable method |
|---|---|
| I want to make the setting from the interface | Method 1: Block invalid box in the common rule |
| I want to do it with a script or the command line | Method 2: WEB-CLI |
Method 1: Block Invalid Box in the Common Rule Recommended
- How it works The body is parsed as JSON, XML or form according to
Content-Type; if parsing fails and the box is checked, a violation is written. - Where it is opened Left Monitor Panel → WAF-Protected vServices → vService → WAF Management → N page types → rule → JSON / Xml / Form → Add Common Rule for …
- RequirementStructure Checks on
- vService type WAF-enabled HTTP vService
- Scope JSON:
…/jsonand+jsontypes · Xml:…/xmland+xmltypes · Form:application/x-www-form-urlencodedandmultipart/form-data
Step-by-Step Configuration
Structure Checks comes on when WAF is turned on; if it has been turned off, in the Left Monitor Panel → WAF-Protected vServices → vService → WAF Management tab, the pencil icon at the top right of the Checks card in the Inspection & Blocking section is clicked (Checks Edit screen).
Structure Checks is set to the on position. While the switch is off, the Block Invalid … Contents boxes are hidden in the form and in the panel and are not applied.
Edit is clicked.
On the WAF Management tab, the N page types row of the host group is clicked (accessing the Page Types screen).
The row of the page type is clicked in the list; the detail panel of the rule opens on the right (accessing the panel). If it will be applied for all paths, the Any Paths row is selected.
The JSON, Xml or Form tab is clicked.
Add Common Rule for … above the table is clicked; if the rule has its own common rule, the button appears as Edit Common Rule for …. The add form opens filled with the values of the Any paths rule in that section.
The Block Invalid JSON Contents (or Block Invalid XML Contents, Block Invalid Form Contents) box is checked. The Block All … Contents box in the same form blocks all bodies of this type; if only malformed bodies are targeted, it is left unchecked (Can I forbid JSON or XML bodies entirely on a page (Block All JSON Contents / Block All XML Contents)?).
Add (Edit when editing) is clicked; the change is applied without a separate deployment step. In a cluster setup, it is also sent to the peer device with the default auto-sync; if Manual Sync Mode is on, it is sent to the peer device manually.
Verification
While the host group is in Blocking mode, a malformed body of the JSON type is sent.
Command: curl -s -o /dev/null -w "%{http_code}\n" -H "Content-Type: application/json" -d '{"ad":' https://www.example.com/api/kayit
418The Attacks tab of the Event Logs record is checked.
Attack area: JSON · Attack name: Block invalid JSON contentsMethod 2: WEB-CLI
- How it works The box is written with WEB-CLI to the
--jsonBlockInvalid,--xmlBlockInvalidor--formBlockInvalidfield. - Where it is opened WEB-CLI →
waf rule-parts - Requirement WEB-CLI access; Structure Checks on (
waf options update poolId <vService> --syncWithDefaultFwRules false --structureChecks true) - vService type WAF-enabled HTTP vService
- Pre-fill difference
addwrites the defaults of the command to the fields that are not written; the…BlockAlland…BlockInvaliddefaults are on
Step-by-Step Configuration
The ID of the default host group is defaultHost; rule IDs are listed in the id column (the Any paths rule appears as default rule):
waf fw-rules list poolId <vService> hostGroupId defaultHostThe row that shows json: (all keys) in the description column is the JSON common part:
waf rule-parts list poolId <vService> hostGroupId defaultHost ruleId <rule>waf rule-parts update poolId <vService> hostGroupId defaultHost ruleId <rule> id <part> --jsonBlockInvalid trueSo that not all JSON bodies are blocked, --jsonBlockAll false is given; the other fields are written with the defaults of the command (jsonKeyCount ≤ 1024, jsonDepth ≤ 8, valueLength 0–1024):
waf rule-parts add poolId <vService> hostGroupId defaultHost ruleId <rule> loc json --jsonBlockAll false --jsonBlockInvalid trueVerification
The part is displayed again.
Command: waf rule-parts show poolId <vService> hostGroupId defaultHost ruleId <rule> <part>
The jsonBlockInvalid line is visible, the jsonBlockAll line is notCommon Mistakes
- Expecting this inspection to catch a malformed body whose
Content-Typeis not JSON. The body is parsed according to the declared type; bodies whose type is not JSON, XML or form are left to the inspections of the Raw tab (What does the Raw tab inspect; what happens to content that cannot be parsed?). - Taking a body that exceeds the processable size for malformed. A body that exceeds the body processing limit or is not completed in time is not parsed at all; this case is determined by Block Unparsed Contents on the Raw tab (What is the difference between Block Unparsed Contents and Block Unexpected Parser Errors?).
- Confusing Block invalid with Block all. Block Invalid … Contents blocks only bodies that cannot be parsed, and Block All … Contents blocks all bodies of that type.
- Relying on the defaults with
addin WEB-CLI. Theaddcommand also writes the…BlockAllfield as on; if--jsonBlockAll falseis not given, all JSON bodies that come to the page are blocked.
How it is done in the documentation
