Sometimes vulnerabilities in older versions of Joomla! and its extensions do not rely on maliciously crafted data but holes in the validation of perfectly normal, innocent-looking data. For example, a well-known e-commerce extension for Joomla! had a vulnerability several years ago which would allow an attacker to create a Super Administrator account by passing an undocumented (and unfiltered) parameter in the new client account creation form. The only way to protect against this kind of attacks is being able to block requests which contain the sort of key-value pairs involved in these vulnerabilities. This can be accomplished with the WAF Deny List.
WAF Deny List
WAF Deny List rules are defined by specifying a combination of a few things.
In order to better explain this, please consider the sample URL
http://www.example.com/index.php?option=com_example&view=foo&task=bar&badidea=oops
Let's consider that we want to block the badidea=oops, badidea=oops1
and so on because if the value of the "badidea" parameter begins with
"oops" the component com_example will do something dangerous, e.g.
give the attacker access to all our data.
Enabled. If you want to temporarily disable a deny list rule when troubleshooting your site you can simply set the Enabled field to No.
Application. Joomla! 4 and later has three applications: the public frontend (the site your visitors see), the administrator backend (where you manage your site) and the API application which handles all URLs beginning with /api. By default, WAF Deny List rules apply only to the frontend of your site. You can choose to apply them in the backend of your site, the API application, or all of the above.
HTTP Verb. The HTTP verb applicable to the request. The most common are GET (access a URL) and POST (submit a form). If you're not sure leave the empty option (three dashes) to have the rule apply to all verbs.
Component. The name of the Joomla component this rule matches. Leaving empty (“– Component –”) matches all components.
View Name. The view of the
component which will be filtered. If left blank the rule will
apply to all views of the component specified in the rule. In a
non-SEF Joomla! URL this is the value of the
view
query parameter (and before the first
ampersand following it, if any). For example, in the sample URL
this is foo
Components using the classic Joomla! MVC might use a
different notation, like
index.php?option=com_foobar&task=foo.bar&badidea=oops
instead of the example URL we noted before. Note the
task=foo.bar
part; its value (foo.bar) is a
composition. The part to the left of the dot (item) is the View
and the value to the right is the Task.
Task. The task of the
component which will be filtered. If left blank the rule will
apply to all tasks of the component and view specified in the
rule. In a non-SEF Joomla! URL this is the value of the
task
query parameter (and before the first
ampersand following it, if any). For example, in the sample URL
this is bar
The note about components using the classic Joomla! MVC applies here as well. If the task has a dot in it then the part to the left of the dot MUST be placed in the View field and the part to the right of the dot MUST be placed in the Task field.
Query Parameter filter type
and Query Parameter. Here you can specify the
name of the query parameter which will be blocked. This is the
name of the parameter after the ampersand and before the equals
sign. In our sample URL it is badidea
You have
three ways to define it:
Exact. What you enter
is the exact name of the query parameter. If you enter
badidea
the rule will filter badidea but not
badidea1, badideamister or thisisabadidea.
Partial. What you enter
is part of the name of the query parameter. If you enter
badidea
the rule will filter badidea,
badidea1, badideamister and thisisabadidea.
Regular Expression.
What you enter is a Regular Expression. For example, if you
enter /idea$/
the rule will filter badidea
and thisisabadidea but NOT badidea1 or badideamister.
Query content. Enter a
regular expression which will be used to match the value of the
query parameter, i.e. what follows the equals sign after the query
parameter name and before the first ampersand after it. In our
example we'd need to use /^oops/
to filter all
values beginning with "oops". If you leave it empty than any value
will be matched by this rule.
Note that it is a very bad idea using a Query Parameter which contains the text option, view, task and Itemid as these are Joomla! reserved keywords. If you create such a rule we can't guarantee what the results will be.
When using Partial and Regular Expression matches be very careful not to filter innocent query parameters. For example, a partial match on id will also block Itemid which is a reserved Joomla! keyword that's internally appended to all URLs of your site. If you still didn't understand this: doing a partial match on id and an empty RegEx for query content will block everyone from accessing any page on your site! If this happens you can rename the plugins/system/admintools folder to admintools-noload (this will prevent Joomla! from loading the System - Admin Tools plugin, therefore disabling Admin Tools' protection), go back to Admin Tools, fix your rule and rename the folder back to admintools to re-activate Admin Tools protection.