Mod_Security rules for Joomla login failures

CoNfOuNd

Member
Feb 20, 2004
22
1
153
Ireland
cPanel Access Level
Root Administrator
As a server admin I am trying to find/create a Mod_Security rule to detect & block multiple login failures on the latest version of Joomla. There's a lot of examples online to prevent brute force attacks (e.g. 5+ requests to the login form) but I haven't found a rule that correctly detects login failures only. The examples I found are also triggered by successful logins.
Some of our hosting clients have many Joomla sites and can legitimately have many logins to Joomla sites within a short time frame, especially when they're working through a list of sites and applying updates. Hence it's really important the rule can tell the difference between successful logins and failed logins.

I found an answer from March 2015 here: mod_security ruleset for Joomla! admin but in my own tests it does not detect login failures. Even with logging enabled it's not detecting anything. I suspect the code is outdated.

I found another ModSec rule published by IT Octopus at A ModSecurity Rule to Block Brute Force Attacks on a Joomla Website | itoctopus The code is below. I tested it on a server but I found it was too sensitive and it blocked me after I logged in + out of Joomla (with correct credentials).

Note: Blocks of code don't seem to be working on cPanel forum today so I've enclosed the code in quotes so I can still share it with you.

<Location /administrator>
SecDefaultAction phase:2,deny,status:403,log,auditlog
SecRule IP:bf_counter "@eq 5" "id:1000002,phase:2,log,block,expirevar:IP.bf_counter=3600,msg:'IP address blocked because of a suspected brute force attack on the Joomla website'"
SecRule ARGS:eek:ption "@streq com_login" "id:1000000,phase:2,chain,t:none,log,pass,msg:'Multiple Joomla authentication failures from IP address', setvar:IP.bf_counter=+1"
</Location>
Next, I found a ModSecurity rule at Brute force protection with ModSecurity » Artefact.io and it's the one I've been using on my servers for many months. It's been working really nicely until yesterday when we found a bug. A client has 10 Joomla websites and they found when they logged into them (with correct credentials) it resulted in their IP being restricted. I was able to replicate this during my own testing. Therefore the code below is the best code we've found yet but the com_login / login lines don't seem to distinguish between login failures and successful logins. It works to prevent general brute force but it doesn't work when a client has many Joomla sites and is legitimately accessing multiple installs at once. This is the code:

# Joomla Brute Force
SecAction "phase:1,pass,setvar:TX.max_requests=6,setvar:TX.requests_ttl=180,setvar:TX.block_ttl=900,initcol:ip=%{REMOTE_ADDR},nolog,id:5001000"
<LocationMatch "/administrator/index.php">
SecAction "phase:2,chain,nolog,id:5001022"
SecRule REQUEST_METHOD "^POST$" "chain"
SecRule ARGS_POST_NAMES "^username$" "chain"
SecRule ARGS_POST_NAMES "^passwd$" "chain"
SecRule ARGS_POST:eek:ption "^com_login$" "chain"
SecRule ARGS_POST:task "^login$" "chain"
SecAction "setvar:ip.request_count=+1,expirevar:ip.request_count=%{TX.requests_ttl}"

SecRule IP:request_count "@ge %{TX.max_requests}" "phase:2,drop,setvar:ip.blocked=1,expirevar:ip.blocked=%{TX.block_ttl},log,msg:'Joomla brute force. Blocking for %{TX.block_ttl} seconds',id:5001023"

</LocationMatch>
Finally, I read some posts that suggested "the P3P header is returned after a successful login" and this could be used in a ModSecurity rule. It was suggested by @godzillante here: mod_security ruleset for Joomla! admin

It uses ModSecurity phase 5 (analysing the log files) so I'm not sure if this is a disadvantage. And more importantly, in my testing I couldn't get it to work. Even with logging enabled, it didn't detect failed logins and didn't restrict access. Here is the code:

SecAction phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},id:5000144
<Locationmatch "/administrator/index.php">
SecRule ip:bf_block "@gt 0" "deny,status:401,log,id:5000145,msg:'ip address blocked for 5 minutes, more than 5 login attempts in 3 minutes.'"
SecRule RESPONSE_HEADERS:P3P "streq 0" "phase:5,t:none,nolog,pass,setvar:ip.bf_counter=0,id:5000146"
SecRule RESPONSE_HEADERS:P3P "!streq 0" "phase:5,chain,t:none,nolog,pass,setvar:ip.bf_counter=+1,deprecatevar:ip.bf_counter=1/180,id:5000147"
SecRule ip:bf_counter "@gt 5" "t:none,setvar:ip.bf_block=1,expirevar:ip.bf_block=300,setvar:ip.bf_counter=0"
</locationmatch>
My objective here is to improve the code "# Joomla Brute Force" (above) because it does block brute force flooding but unfortunately it also blocks users when they are legitimately logging into Joomla a lot. I need code that can tell the difference between a login failure and a successful login to Joomla. I've been working on this for some time so I'm reaching out to the community here. Thanks in advance!
 
Last edited by a moderator:

cPRex

Jurassic Moderator
Staff member
Oct 19, 2014
16,597
2,615
363
cPanel Access Level
Root Administrator
Thanks for the great post. We are aware of the code block issue and are hoping to get that resolved soon.

I don't have much I can add about the ModSecurity rules, but I'll leave this post marked as New for a while to see if other users can contribute their experience.
 

r7diego

Registered
Oct 28, 2020
3
0
1
Uruguay
cPanel Access Level
Reseller Owner
Hi, i have a problem similar to the one described, modsecurity confuses regular activity in the joomla administrative folder with brute force attacks.

Happens all too often when my clients update multiple items as part of regular maintenance, a pain in the @@@