@mattab opened this Issue on January 26th 2012 Member

Our security policy aims to make security a principal design behind Piwik. One aspect that bugs me currently is that good old brute force attacks could be vector of penetration in Piwik (if eg. attacker knows the login).

We should provide a core mechanism that would lock out, for 30min for example, a user after N failed attemps. Settings could be changed by the Super User and feature would be enabled by default, lock 30 min out after 5 failed attempts.

Implementation proposal:

  • Record, using Piwik_SetOption, count of lockdown for each IP that fails to enter valid login / pwd combination
  • After N failures, lock IP down and refuse authentication (even if the combination is actually valid!).
  • Document as FAQ, linked from UI, the sql to delete all locked out IPs in case the SU was actually locked out and can't wait.
@sgiehl commented on January 27th 2012 Member

I would suggest to handle that the way like windows and many other software does. After 3 failed attemnds, lock the account and let the user wait a few minutes until he can retry. With every following failure raise the time to wait. I would do that global and not for each IP as it is too easy to change/switch the IP. Maybe we could implement an option to unlock the account with an token send by mail or something like that.

@robocoder commented on January 27th 2012 Contributor

If there's a lockdown, it should be by ip or /24.

The piwik_option table is not an appropriate place for this, imho, given the other scenarios I listed in #2794. We need.to keep track of the type of attack, ip, number of attempts, and timestamp of last attempt.

There should be some flexibility in the implementation to accomodate different responses to an attack. Can this implemented as a plugin?

@mattab commented on October 5th 2012 Member

The counter increase for a given IP should take place for any request which authenticates:

  • failed login attempts (e.g., brute force)
  • failed lost password requests / username/email check
  • password reset with invalid (e.g., expired) reset token (e.g., replay)

For these, we should automatically blacklist the IP for X seconds, after N failed attempts within M seconds.

For an extended security (possible for a Version 2 of this feature since it complicates it)

  • API request with invalid token
    Here maybe we shouldn't blacklist as there could be an error in a code calling the API which would blacklist possibly other functions calling API with a proper token. For a user calling the API with a wrong token, we should simply alert at first, and/or have an opt-in black list limit ?
@mainboarder commented on November 5th 2012

I would like an extra subdirectory for administration (like ./admin)
So the login could be restricted to ip ranges or a single ip via .htaccess or protected with basic auth
But I think it would be a huge change in the code :/

Maybe a fail2ban lockdown could be as usefull as the .htaccess feature.

@mattab commented on November 6th 2013 Member
  • We should also use this mechanism to protect against brute forcing the SMS authorization mechanism (since code is 5 chars, could be brute forced to send unwanted texts)
@anonymous-piwik-user commented on January 12th 2014

I would also like this feature to be implemented and suggest also having an "immediately lock out IP when trying invalid/non-existent usernames" feature.

Also, email reports of when login attempts happen would be useful so you have a feel for how often you were being targeted.

I find both these features useful when using Wordfence for my WordPress sites.

@robocoder commented on January 13th 2014 Contributor

I suggest adding new event hooks and a plugin that leverages the PHPIDS or Expose libraries.

@mainboarder commented on January 13th 2014

Replying to ham12343:

I would also like this feature to be implemented and suggest also having an "immediately lock out IP when trying invalid/non-existent usernames" feature.

I think lockdown if a wrong username is used is useless or even a risk:

  • what if you have a typo? like "hsm1243" instead of "ham12343"
  • attackers could try to find out a correct username. it is found if the lockdown doesn`t happen immediately. (as long as there is a feedback like "your logins are now ignored")
@mattab commented on December 11th 2014 Member

Moving to short term as we'd like to be pro-active with security and this issue is an important protection layer.

@gaumondp commented on December 11th 2014

Some ideas, could be one or all...

  1. Lockdown IP after X attempts. Some kind of blacklist management will be need.
  2. On bad credential wait X seconds before showing login screen (minimize web brute force).
  3. Send an email to admin after X unsuccessful attempts.

The first one is the more complex, 2 and 3 seems quite easy to implement.

@dustindauncey commented on December 15th 2014

I'd also like to see the attempts logged somewhere too, mainly so that users can implement fail2ban with Piwik with ease.

@mattab commented on December 15th 2014 Member

@dustindauncey sure we will log them in Piwik application log

@jkraemer commented on March 7th 2015

Actually just adding the logging (including timestamp and remote ip) might solve the whole issue for a lot of people. Fail2ban is made exactly for this purpose, there's no need to re-invent the wheel here imho.

@tsteur commented on October 29th 2015 Member

I think this is quite an important issue for security of Piwik. It is not too difficult to brute force installations otherwise.

Lockdown IP after X attempts. Some kind of blacklist management will be need.

After eg 50 attempts within 12 hours I would lock down IP (we'd need config for this if all users come from same IP or reuse trust_cookies setting which is used in Intranets and depending on this disable it etc).

On bad credential wait X seconds before showing login screen (minimize web brute force).

After say 5 wrong login attempts for same user, I would make login slower (also on API level but won't be trivial) each time. Eg in the beginning wait 1 second, next try wait 3 seconds, next try wait 6 seconds ... This needs to be implemented wisely since one could "shut down" a Piwik under circumstances by doing wrong login requests on purpose etc. Won't be trivial to implement I reckon but I'm sure for such things there are good solutions available on the internet

One could otherwise just crawl for several Piwik instances, try most common usernames with some most common passwords and I'm sure it's possible to get access to some installations

@mattab commented on October 29th 2015 Member

@tsteur moved to Short term and added Major tag - how much effort do you think it would take to seriously mitigate this security risk?

@gaumondp commented on October 30th 2015

In TYPO3 we got Backend access with a sleep(5) on bad login for 15 years. There was a discussion about brute force that could be interesting to read :


@tsteur commented on November 1st 2015 Member

From https://forum.typo3.org/index.php/t/196184/ :

You will get a warning email (if you set up an address in the install tool) after four unsuccessful attempts anyway.

This could be interesting in general and useful, I'll create an issue for this: https://github.com/piwik/piwik/issues/9140

Also maybe a good read:

I think a first version would be something between 1-2 days. It's really not easy I think since there are so many possibilities to workaround this and it would be possible to lock out real users.

@mattab commented on November 2nd 2015 Member

FYI here is the UI for the "Limit login attempt" wordpress plugin which we use on piwik.org:

wp limit login attemps

@ghub2015 commented on October 17th 2016

I have to agree with the comments that suggest just logging Piwik login attempts will be very useful.

That way we can use fail2ban, or other preferred method for ratelimiting or blocking attackers.

I am still very concerned about protecting Piwik without this.

@criwe commented on November 27th 2016


@tsteur commented on November 27th 2016 Member

FYI: There is https://plugins.piwik.org/ActivityLog which logs any login attempts etc and shows them in the UI. It is planned to show Country + IP .

For logging the requests a PR would be appreciated 👍 It may not be too hard. @ghub2015 what kind of format would be needed for this in the logs? Or is it format independent? Asking in case someone wants to add this feature

@ghub2015 commented on January 28th 2017

@tsteur, being able to parse standard Apache/Nginx log format (or any other webserver), is key for fail2ban. (In the case of Apache, it may be defined in the LogFormat stanza in /etc/apache2/apache2.conf)

So for example, logging an HTTP status code 401 on failed login attempt would be amazing!

These links may be of interest:

Fail2ban and Apache:

HTTP Status code reference:

@mannp commented on March 18th 2017

Wondered if there had been any progress on this one at all :)

Thanks in advance

@patrickbr commented on July 23rd 2017 Contributor

I added a simple plugin called LoginFailLog to the marketplace. Once activated, every failed login attempt is written to the Piwik log file like this:

WARNING LoginFailLog[2017-07-22 23:35:20] [b215d] Failed login from 'patrick'.
WARNING LoginFailLog[2017-07-22 23:35:20] [b215d] Failed login from with username 'patrick'.

You can use this plugin to protect Piwik with fail2ban or similar tools. See the README for a fail2ban example filter.

There is one problem though: Piwik logs everything in UTC time, for whatever reason. This is not configurable and may cause problems. For fail2ban, a workaround is described in the README.

@ghub2015 commented on July 23rd 2017

@patrickbr that is awesome, thanks for this!

I will test and give feedback.

Let me just recommend (before even testing it) that you consider adding "Piwik" to what is logged so that it becomes:

WARNING Piwik LoginFailLog[2017-07-22 23:35:20] [b215d] Failed login from 'patrick'.
WARNING Piwik LoginFailLog[2017-07-22 23:35:20] [b215d] Failed login from with username 'patrick'.

Just good for housekeeping/visual searching/grep'ing

@patrickbr commented on July 23rd 2017 Contributor

@ghub2015 Everything before the "Failed login..." message is written by Piwik. The plugin uses the built-in logging system. Adding "Piwik" after "WARNING" would be redundant, as the piwik.log file only contains Piwik logs :)

@mattab commented on July 24th 2017 Member

Nice trick @patrickbr :+1:

There is one problem though: Piwik logs everything in UTC time, for whatever reason.

it seems there's an issue with our logger, as it does not log the timezone. LoginFailLog[2017-07-22 23:35:20] should include the timezone maybe LoginFailLog[2017-07-22 23:35:20 UTC] (would need to check whether this is the valid way). Please feel free to create a pull request for this :+1:

@Findus23 commented on July 24th 2017 Member


It seems like Fail2Ban does support UTC:https://github.com/fail2ban/fail2ban/pull/1583, https://github.com/fail2ban/fail2ban/issues/1575

But for that to work the log line needs to include the timezone as @mattab mentioned.

@patrickbr commented on July 24th 2017 Contributor

@mattab I created a pull request for this: https://github.com/piwik/piwik/pull/11893

@flaviusturc24 commented on April 27th 2018

I have a problem, I tested and it shows that IP is banned, but when I enter correct credentials, it is loggin in. What to do in this case?

@patrickbr commented on April 28th 2018 Contributor

@flaviusturc24 fail2ban works IP based on the connection level, it has nothing to to with your credentials. nor does it prevent you from logging in. It prevents you from even reaching the server/login page. If your fail2ban log shows that your IP is banned, but you can still reach the login page, then something is either misconfigured in fail2ban, or you have some rule in your firewall that allows traffic from IP to come through, regardless of any other rule.

Powered by GitHub Issue Mirror