Adding Rules in the Application Profile¶
To add a new rule, go to the Rules tab.
Rules can be added to both existing and new branches. They can be created from scratch or based on one of the existing branches.
To add a rule to an existing branch, click Add rule (after hovering the mouse cursor over the branch description line, the button will appear in the pop-up menu on the right). You can also perform this operation on the rule page of this branch.
If necessary, it is possible to modify the branch to which a rule will be added. For this, click on the If request is clause in the rule-adding form and make changes to the branch description conditions. If a new branch is created, it will appear on the screen, and the application structure view will be updated.
Branch Description¶
A branch description consists of a set of conditions for various parameters that an HTTP request must fulfill; otherwise, the rules associated with this branch will not be applied. Each line in the If request is section of the rule-adding form refers to a separate condition comprised of three fields: point, type, and comparison argument. The rules described in the branch are only applied to the request if all the conditions are fulfilled.
To configure the set of conditions, both the URI constructor and the advanced edit form can be used.
URI constructor¶
Working with URI constructor¶
URI constructor allows configuring the rule conditions by specifying the request method and endpoint in only one string:
-
For the request method, the URI constructor provides the particular selector. If the method is not selected, the rule will be applied to requests with any method.
-
For the request endpoint, the URI constructor provides the particular field accepting the following value formats:
Format Examples and request point values Full URI including the following components: - Scheme (the value is ignored, you can explicitly specify the scheme by using the advanced form)
- Domain or an IP address
- Port
- Path
- Query string parameters
https://example.com:3000/api/user.php?q=action&w=delete
[header, 'HOST']
-example.com:3000
[path, 0]
-api
[path, 1]
-∅
[action_name]
-user
[action_ext]
-php
[query, 'q']
-action
[query, 'w']
-delete
URI with some components omitted example.com/api/user
[header, 'HOST']
-example.com
[path, 0]
-api
[path, 1]
-∅
[action_name]
-user
[action_ext]
-∅
http://example.com/api/clients/user/?q=action&w=delete
[header, 'HOST']
-example.com
[path, 0]
-api
[path, 1]
-clients
[path, 2]
-∅
[action_name]
-user
[query, 'q']
-action
[query, 'w']
-delete
/api/user
`[header, 'HOST']
- any value[path, 0]
-api
[path, 1]
-∅
[action_name]
-user
[action_ext]
-∅
URI with *
meaning any non‑empty value of the componentexample.com/*/create/*.*
[header, 'HOST']
-example.com
[path, 0]
- any non‑empty value (hidden in the advanced edit form)[path, 1]
-create
[path, 2]
-∅
[action_name]
- any non‑empty value (hidden in the advanced edit form)[action_ext]
- any non‑empty value (hidden in the advanced edit form) The value matches
example.com/api/create/user.php
and does not matchexample.com/create/user.php
andexample.com/api/create
.URI with **
meaning any number of components including its absenceexample.com/**/user
[header, 'HOST']
-example.com
[action_name]
-user
[action_ext]
-∅
The value matches
example.com/api/create/user
andexample.com/api/user
.
The value does not matchexample.com/user
,example.com/api/user/index.php
andexample.com/api/user/?w=delete
.example.com/api/**/*.*
[header, 'HOST']
-example.com
[path, 0]
-api
[action_name]
- any non‑empty value (hidden in the advanced edit form)[action_ext]
- any non‑empty value (hidden in the advanced edit form) The value matches
example.com/api/create/user.php
andexample.com/api/user/create/index.php
and does not matchexample.com/api
,example.com/api/user
andexample.com/api/create/user.php?w=delete
.URI with the regular expression to match certain component values (regexp must be wrapped in {{}}
)example.com/user/{{[0-9]}}
[header, 'HOST']
-example.com
[path, 0]
-user
[path, 1]
-∅
[action_name]
-[0-9]
[action_ext]
-∅
The value matches
example.com/user/3445
and does not matchexample.com/user/3445/888
andexample.com/user/3445/index.php
.
The string specified in the URI constructor is automatically parsed into the set of conditions for the following request points:
-
method
-
header
. The URI constructor allows specifying only the headerHOST
. -
path
,action_name
,action_ext
. Before confirming the rule creation, please ensure the values of these request points are parsed in one of the following ways:- Explicit value of certain
path
number +action_name
+action_ext
(optional) - Explicit value of
action_name
+action_ext
(optional) - Explicit value of certain
path
number withoutaction_name
and withoutaction_ext
- Explicit value of certain
-
query
The value specified in the URI constructor can be completed by other request points available only in the advanced edit form.
Using wildcards¶
Can you use wildcards when working with URI constructor in Wallarm? No and yes. "No" means you cannot use them classically, "yes" means you can achieve the same result acting like this:
-
Within parsed components of your URI, instead of wildcards, use regular expressions.
-
Place
*
or**
symbol into the URI field itself to replace one or any number of components (see examples in the section above).
Some details
The syntax of the regular expression is different from the classical wildcards, but the same results can be achieved. For example, you want to get a mask corresponding to:
-
something-1.example.com/user/create.com
and -
anything.something-2.example.com/user/create.com
...which in classical wildcards you would try to get by typing something like:
*.example.com/user/create.com
But in Wallarm, your something-1.example.com/user/create.com
will be parsed into:
...where something-1.example.com
is a header
-HOST
point. We mentioned that wildcard cannot be used within the point, so instead we need to use regular expression: set the condition type to REGEX and then use the regular expression Wallarm specific syntax:
-
Do not use
*
in a meaning "any number of symbols". -
Put all the
.
that we want to be interpreted as "actual dots" in square brackets:something-1[.]example[.]com
-
Use
.
without brackets as replacement of "any symbol" and*
after it as quantifier "0 or more repetitions of the preceding", so.*
and:.*[.]example[.]com
-
Add
$
in the end of the expression to say that what we created must end our component:.*[.]example[.]com$
The simpler way
You can omit
.*
and leave only[.]example[.]com$
. In both cases, Wallarm will assume that any character can appear before[.]example[.]com$
any number of times.
Advanced edit form¶
Points¶
The point field indicates which parameter value should be extracted from the request for comparison. At present, not all of the points that can be analyzed by the filter node, are supported.
The following points are currently supported:
-
application: application ID.
-
proto: HTTP protocol version (1.0, 1.1, 2.0, ...).
-
scheme: http or https.
-
uri: part of the request URL without the domain (for example,
/blogs/123/index.php?q=aaa
for the request sent tohttp://example.com/blogs/123/index.php?q=aaa
). -
path, action_name, action_ext is hierarchical URI component sequence where:
- path: an array with URI parts separated by the
/
symbol (the last URI part is not included in the array). If there is only one part in the URI, the array will be empty. - action_name: the last part of the URI after the
/
symbol and before the first period (.
). This part of the URI is always presented in the request, even if its value is an empty string. - action_ext: the part of the URI after the last period (
.
). It may be missing in the request.
- path: an array with URI parts separated by the
-
query: query string parameters.
-
header: request headers. When you enter a header name, the most common values are displayed in a drop-down list. For example:
HOST
,USER-AGENT
,COOKIE
,X-FORWARDED-FOR
,AUTHORIZATION
,REFERER
,CONTENT-TYPE
.Managing
HOST
header rules for FQDNs and IP addressesIf the
HOST
header is set to an FQDN, requests targeting its associated IP address will not be affected by the rule. To apply the rule to such requests, set theHOST
header value to the specific IP in the rule conditions, or create a separate rule for both the FQDN and its IP.When placed after a load balancer that modifies the
HOST
header, the Wallarm node applies rules based on the updated value, not the original. For example, if the balancer switches theHOST
from an IP to a domain, the node follows rules for that domain. -
method: request methods. If the value is not explicitly specified, the rule will be applied to requests with any method.
Condition type: EQUAL (=
)¶
The point value must match precisely with the comparison argument. For example, only example
matches with the point value example
.
EQUAL condition type for the HOST header value
To cover more requests with the rules, we have restricted the EQUAL condition type for the HOST header. Instead of the EQUAL type, we recommend using the type IEQUAL that allows parameter values in any register.
If you have previously used the EQUAL type, it will be automatically replaced with the IEQUAL type.
Condition type: IEQUAL (Aa
)¶
The point value must match with the comparison argument in any case. For example: example
, ExAmple
, exampLe
match with the point value example
.
Condition type: REGEX (.*
)¶
The point value must match the regular expression.
Regular expression syntax
To match requests with regular expressions, the PIRE library is used. Mostly, the syntax of expressions is standard but has some specifics as described below and in the README file of PIRE repository.
Show regular expression syntax
Characters that can be used as‑is:
- Lowercase Latin letters:
a b c d e f g h i j k l m n o p q r s t u v w x y z
- Capital Latin letters:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
- Digits:
0 1 3 4 5 6 7 8 9
- Special characters:
! " # % ' , - / : ; < = > @ ] _ ` }
- Whitespaces
Characters that must be placed into square brackets []
instead of escaping with \
:
. $ ^ { [ ( | ) * + ? \ & ~
Characters that must be converted to ASCII according to ISO‑8859:
- UTF‑8 characters (for example, the character
ʃ
converted to ASCII isÊ
)
Character groups:
.
for any character except a newline()
for grouping regular expressions, searching symbols present inside()
or establishing a precedence order[]
for a single character present inside[]
(case sensitive); the group can be used for the specific cases:- to ignore case (for example,
[cC]
) [a-z]
to match one of lowercase Latin letters[A-Z]
to match one of capital Latin letters[0-9]
to match one of digits[a-zA-Z0-9[.]]
to match one of lowercase, or capital Latin letters, or digits, or dot
- to ignore case (for example,
Logic characters:
~
is equal to NOT. The inverted expression and the character must be placed into()
,
for example:(~(a))
|
is equal to OR&
is equal to AND
Characters to specify string boundaries:
^
for the start of the string$
for the end of the string
Quantifiers:
*
for 0 or more repetitions of the preceding regular expression+
for 1 or more repetitions of the preceding regular expression?
for 0 or 1 repetitions of the preceding regular expression{m}
form
repetitions of the preceding regular expression{m,n}
form
ton
repetitions of the preceding regular expression; omittingn
specifies an infinite upper bound
Character combinations that work with specifics:
^.*$
is equal to^.+$
(empty values does not match with^.*$
)^.?$
,^.{0,}$
,^.{0,n}$
are equal to^.+$
Temporarily not supported:
- Character classes like
\W
for non-alphabetics,\w
for alphabetics,\D
for any non-digits,\d
for any decimals,\S
for non-whitespaces,\s
for whitespaces
Not supported syntax:
- Three-digit octal codes
\NNN
,\oNNN
,\ONNN
\cN
passing control characters via\c
(for example,\cC
for CTRL+C)\A
for the start of the string\z
for the end of the string\b
before or after the whitespace character in the end of the string??
,*?
,+?
lazy quantifiers- Conditionals
Testing regular expressions
To test the regular expression, you can use the cpire utility on supported Debian or Ubuntu:
-
Add Wallarm repository:
sudo apt update sudo apt -y install dirmngr curl -fSsL https://repo.wallarm.com/wallarm.gpg | sudo gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/wallarm.gpg --import sudo chmod 644 /etc/apt/trusted.gpg.d/wallarm.gpg sh -c "echo 'deb https://repo.wallarm.com/debian/wallarm-node bullseye/4.8/' | sudo tee /etc/apt/sources.list.d/wallarm.list" sudo apt update
-
Install the cpire utility:
-
Run the cpire utility:
-
Enter the value to check whether it matches with the regular expression. The utility will return the result:
0
if the value matches with the regular expressionFAIL
if the value does not match with the regular expression- Error message if the regular expression is invalid
Specifics of handling the
\
characterIf the expression includes
\
, please escape it with[]
and\
(for example,[\\]
).
Examples of regular expressions added via Wallarm Console
-
To match any string that includes
/.git
-
To match any string that includes
.example.com
-
To match any string ending with
/.example.*.com
where*
can be any symbol repeated any number of times -
To match all IP addresses excluding 1.2.3.4 and 5.6.7.8
-
To match any string ending with
/.example.com.php
-
To match any string that includes
sqlmap
with letters in lower and upper case:sqLmAp
,SqLMap
, etc -
To match any string that includes one or several values:
admin\.exe
,admin\.bat
,admin\.sh
,cmd\.exe
,cmd\.bat
,cmd\.sh
-
To match any string that includes one or several values:
onmouse
with letters in lower and upper case,onload
with letters in lower and upper case,win\.ini
,prompt
-
To match any string that starts with
Mozilla
but does not contain the string1aa875F49III
-
To match any string with one of the values:
python-requests/
,PostmanRuntime/
,okhttp/3.14.0
,node-fetch/1.0
Condition type: ABSENT (∅
)¶
The request should not contain the designated point. In this case, the comparison argument is not used.
Rule¶
The added request processing rule is described in the Then section.
The following rules are supported: