Sunday, September 15, 2013

Blocking brute force attacks against the TYPO3 backend login using ModSecurity

Since the last few weeks I have noticed a constantly growing amount of failed TYPO3 backend login attempts on websites I administer. It seems I'm not alone with this problem, since a few other TYPO3 users are reporting the same issues. The method always seems to be the same - someone is doing a brute force attack against the password of the TYPO3 backend user "admin". The attack seems to be automated, takes several hours and comes from various IP addresses and from different countries in the world.

If you do not have any TYPO3 backend account with the username "admin", you could just ignore the case that someone is trying to hack your TYPO3 installation. Well, since I have configured a [BE][warning_email_addr] my mailbox gets flooded with thousands of emails about failed TYPO3 login attempts.

But what is the best way to handle and block those attacks? When I faced the first attack, I just denied the IP address of the attacker into the local .htaccess file of the TYPO3 installation. This method is implemented very quick, but always requires manual steps and is only valid for a given IP address. In the austrian TYPO3 forum I have read about a TYPO3 extension, which extends the TYPO3 backend login and is able to automatically blacklist IP addresses for failed login attempts. This idea seems to be good in general, but when you administer just more than one TYPO3 installation, the installation and configuration process of the extension can be very time consuming. I finally ended up with the solution, that once again ModSecurity seems to be the best way to handle this kind of attacks to TYPO3. During research I found an article about brute force protection using ModSecurity. Sadly the rules did'nt fit out of the box into my setup, so I had to create my own ruleset.

Below follows a ModSecurity ruleset, which blocks the IP address of an attacker for 10 minutes, if there were more than 5 failed TYPO3 authentication attempts from that IP address. Please note, that the ruleset only was tested with ModSecurity 2.7.x together with the OWASP ModSecurity Core Rule Set.

<IfModule mod_security2.c>

    # TYPO3 backend login brute force protection
    <Location "/typo3/index.php">
        # Turn on security engine (if disabled)
        SecRuleEngine On

        # Deny IP address if too many TYPO3 authentication failures
        SecRule IP:bf_block "@eq 1" \
        "id:'5000102', \
        msg:'IP address temporarily blocked due to too many TYPO3 authentication failures', \
        phase:2, \
        log, \

        # Check for TYPO3 authentication failure and increment counter
        SecRule RESPONSE_BODY "LOGIN_ERROR### begin" \
        "id:'5000100', \
        msg:'Failed TYPO3 authentication attempt', \
        phase:5, \
        t:none, \
        setvar:IP.bf_counter=+1, \
        expirevar:IP.bf_counter=3600, \
        nolog, \

        # Check for too many failures from a single IP address
        SecRule IP:bf_counter "@gt 5" \
        "id:'5000101', \
        msg:'Too many TYPO3 authentication failures from IP address', \
        phase:5, \
        t:none, \
        setvar:IP.bf_block, \
        setvar:!IP.bf_counter, \
        expirevar:IP.bf_block=600, \
        log, \



The ruleset creates a counter (IP.bf_counter) for each IP address, when a failed TYPO3 login is monitored. A failed login is identified by the string "LOGIN_ERROR### begin" in the response body. I don't check for the occourence of the string "Your login attempt did not succeed", since some TYPO3 installations may have a e.g. german or danish backend login and within this the resulting error message will be translated and the rule would not match.

I've decided not to log each failed login attempt, since it fills up the ModSecurity audit log with the complete response from the TYPO3 backend login. If the counter is greater than 5, the counter is unset and a new variable (IP.bf_block) with a lifetime of 600 seconds is defined. Depending on this counter, the IP address gets blocked with a 403 error.

If you have blocked your own IP address during to too many failed login attempts, you have to unset the counter variable by modifying your ruleset. This is not very practical, so another possibility to unset the variable is to simply delete the file /tmp/ip.pag - this is where ModSecurity stores all variables in a default setup. Note, that deleting the file will remove all variables set by ModSecurity. Also I don't know, if deleting the file will result in any other unwanted side-effects, so be carefull with that.

Besides using ModSecurity to protect TYPO3 websites against known and unknown attacks, I also recommend using a Yubikey to add two-factor authentication to TYPO3 admin accounts.