Can I block requests that contain debug/test parameters?
Short answer
Yes, on the HTTP vService. In the Query Parameter condition, the parameter name (e.g. debug) is written and Is present is selected as the matching; the condition is bound to a Block action, and a request that carries the parameter in the debug=… form is blocked before it reaches the Backend Service, whatever its value is. The valueless ?debug form, multiple parameters and case variants can be caught with Regex in a single Path + Query condition. If WAF is enabled, the Allowed Query Parameters list of the page type counts every parameter name that is not in the list as a violation.
Problem: Debug Parameters Stay Open in the Live Environment
During development, applications can return additional information with parameters such as debug, test or trace. When these parameters stay open in the live environment, error details and internal information can become visible to the outside; the requests that carry these parameters are meant never to reach the Backend Service.
Solution: Four Methods
Methods 1 and 2 set up the same Block action with different conditions; Method 3 is the positive list of WAF; Method 4 is the command line equivalent of Method 2.
| Your situation | Suitable method |
|---|---|
| One or a few known parameter names | Method 1: Query parameter (Is present) + Block |
Multiple parameters in a single condition; case variants such as Debug, DEBUG must also be caught | Method 2: Path + Query (Regex) + Block |
| I have a WAF license; only the allowed parameter names must be accepted | Method 3: WAF → Allowed Query Parameters |
| Setup from the command line | Method 4: WEB-CLI |
Method 1: Query Parameter (Is Present) + Block Recommended
- How it works The condition checks whether the parameter whose name is entered is present in the query string; it matches whatever the parameter value written with
=is (?debug=1,?debug=true). The?debugform that carries no value is not caught with this condition; to catch it as well, Method 2 is used. The parameter name is case sensitive. - Where it is openedLoad Balancer → Conditions → Query Parameter · Load Balancer → Actions → Block
- Requirement None
- vService type HTTP (the Query parameter condition and the Block action are used only on the HTTP vService)
Step-by-Step Configuration
The condition form is opened with Load Balancer → Conditions → Add (how to add).
Condition Name = debug-param, Criteria = Query Parameter are selected; debug is written in the Query Parameter field and Is present is selected in the matching list. With this selection, the Query and Case Insensitive fields are hidden. A separate condition is created for each parameter (debug parameter scenario).
The condition is saved with Add; if Add & Repeat is used for another parameter (e.g. test), the form stays open for the new condition.
The action form is opened with Load Balancer → Actions → Add.
Action Name = debug-engelle, Action Type = Block are selected; Execution Level is left at the default On Request and Deny Type at the default Standard; Status Code is 403 by default (404 can be selected to hide the existence of the page). If an information page is to be shown instead of a block, Show Content is selected instead of Block; since Status code is 200 by default in this action, 403 or 404 must be selected (Can I return content directly for certain requests without going to the backend (Show Content)?).
debug-param is selected in the Conditions field; if there are multiple parameter conditions, they are bound with or in the same group. If the Conditions field is left empty, the action is applied to all traffic.
The action is saved with Add.
On the Load Balancer → Load Balancer vService List screen, the HTTP vService is selected and the edit form is opened with Edit.
debug-engelle is selected in the Details → Actions field. The action does not work unless it is added to the vService.
The form is saved with Save. No change is required on the Backend Service side. In a cluster, the change is transferred to the peer device automatically by default; if Manual Sync Mode is on, it is sent with Synchronize.
Verification
Command: curl -s -o /dev/null -w '%{http_code}' 'https://www.example.com/?debug=1'
403Command: curl -s -o /dev/null -w '%{http_code}' 'https://www.example.com/'
200Method 2: Path + Query (Regex) + Block
- How it works The Path + Query condition evaluates the path and the query string together (e.g.
/urun?debug=1); with Regex and Case Insensitive, multiple parameter names and case variants are caught in a single condition. The value is compared in its raw (URL-encoded) form. - Where it is openedLoad Balancer → Conditions → Path + Query
- Requirement None
- vService type HTTP
Step-by-Step Configuration
The condition form is opened with Load Balancer → Conditions → Add.
Condition Name = debug-param-regex, Criteria = Path + Query are selected, and Regex is selected in the matching list; [?&](debug|test|trace)(=|&|$) is written in the Query field and Case Insensitive is checked. The pattern catches the ?debug=1, ?x=1&TEST, ?trace requests; it does not catch the ?debugger=1 or ?x=debug requests.
The condition is saved with Add.
Steps 4–7 of Method 1 are applied; debug-param-regex is selected in the Conditions field.
Steps 8–10 of Method 1 are applied: the vService is opened with Edit, the action is selected in the Details → Actions field and the form is saved with Save.
Verification
Command: curl -s -o /dev/null -w '%{http_code}' 'https://www.example.com/?Debug=1'
403Method 3: WAF → Allowed Query Parameters
- How it worksAllowed Query Parameters in the page type is a positive list: every parameter name that is not in the list is scored as a violation in the Structure Policies category. The name matching is raw and case sensitive.
- Where it is opened Left Monitor Panel → WAF-Protected vServices → vService → WAF Management → Page Types → rule → Query tab
- Requirement WAF license; WAF-enabled HTTP vService; Argument Checks on
- vService type HTTP
Step-by-Step Configuration
If WAF is not on in the vService, the HTTP vService is edited, the WAF box under Details is checked, and the form is saved with Save; details: How do I attach WAF, L7 DDoS & Threat Protection and AGS to a vService?
In the WAF Management tab, the rule (Any paths for the whole site) is opened from the Page Types list; in the Query tab, Add common rule for Query (Edit common rule for Query if a rule exists) is clicked (screen).
The Allowed Query Parameters restriction is turned on, and the parameter names that the application uses are added one by one. Names such as debug, test are not added to the list. If the number of names in the list exceeds the Max. Allowed Arguments limit (25 by default), the list check is disabled for this rule.
The form is saved with Add. If Argument Checks is off, this check is not generated.
In the WAF Management tab, with the Edit button of the mode card, WAF Mode = Blocking Mode is selected and saved (WAF mode Edit screen). WAF starts in Learning mode; in Learning mode this check does not work (only a restriction suggestion is learned), and in Monitor mode the violation is reported but the request is passed.
Verification
A request is sent with ?debug=1; the WAF-Protected vServices → vService → Event Logs screen is checked.
Allowed Query Parameters violation, Attack blockedMethod 4: WEB-CLI
- How it works The condition and the Block action are created with
lb condition/lb action, and the action is added to the vService withlb service. Since there is no parameter name field for the Query parameter condition in WEB-CLI, the Path + Query condition is used. - Where it is opened TR7 WEB-CLI →
lb condition·lb action·lb service - Requirement WEB-CLI access
- vService type HTTP
Step-by-Step Configuration
WEB-CLI runs each line as a separate command; the commands are written on a single line. The | character splits the command in two even inside quotes; for this reason, the (debug|test|trace) pattern in Method 2 cannot be written in WEB-CLI. A separate condition that does not contain | is created for each parameter, and the conditions are combined with or in the action. If working with a single pattern is preferred, the condition is entered from the interface (Method 2).
The [?&]debug([=&].*)?$ pattern catches the same requests as the debug part of the pattern in Method 2: ?debug, ?debug=1, ?x=1&debug&y=2; ?debugger=1 and ?x=debug do not match (criteria that match content).
lb condition add criteria pathq query '[?&]debug([=&].*)?$' --content_placement regex --caseInsensitive true --name debug-param
lb condition add criteria pathq query '[?&]test([=&].*)?$' --content_placement regex --caseInsensitive true --name test-paramThe --cond field of the action requires the ID of the condition, not its name. lb condition add gives no output when it succeeds; the IDs are seen in the id column of the list below (they start with lbConditions-).
lb condition listThe two conditions are combined with or inside quotes; if Status code is not specified, it is 403 (blocking actions).
lb action add type deny name debug-engelle --cond "<debug-param-id> or <test-param-id>"The rules.0, rules.1… lines show the actions bound to the vService.
lb service show <vService>The new action is written to the first empty index, that is, to the number of existing actions. In the example, since the vService has two actions (rules.0, rules.1), --rules.2 is used; writing to a filled index replaces the action there.
lb service update id <vService> --rules.2 debug-engelleVerification
Command: curl -s -o /dev/null -w '%{http_code}' 'https://www.example.com/?x=1&TEST=2'
403Common Mistakes
- Assuming that Case insensitive applies to the parameter name. In the Query parameter condition, the name is case sensitive, and while Is present is selected, the Case insensitive field is not visible; for case variants, Method 2 is used.
- Selecting Exact match instead of Is present. Exact match catches only the entered value;
?debug=trueand?debug=1remain different. - Leaving Block without a condition. If the Conditions field is empty, all traffic is blocked.
- Writing a pattern that contains
|in WEB-CLI. WEB-CLI splits the command at the|character; the pattern is broken up and the command runs incorrectly. - Writing the condition name in the
--condfield. In WEB-CLI,--condexpects the condition ID; if the name is written, the action is bound to a condition that does not exist. - Not adding the action to the vService. Why is my Action not triggering?
How it is done in the documentation
