WAF Deny List

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 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.