Things seem to work well as long as I do not use the feature to increase the delay for failed login attempts. As soon as I select this feature (with eg a delay base time of 7 seconds) I cannot login any more at all to the site. After entering username and password and clicking on login, nothing is being returned, ever.
Had to use something like PHPMyAdmin to set the status of this module to "0" in table "system" to disable the module and gain access to the web site again. And that is why I submitted the bug with priority critical, as this workaround may not be obvious for novice Drupal users.
(Everything, including the increase delay feature, worked fine with version 6.x-1.0-beta1. I am experiencing this problem on two Drupal 6.13 sites.)
| Comment | File | Size | Author |
|---|---|---|---|
| #5 | login_security_558624_1.patch | 4.34 KB | ilo |
| #4 | login_security_558624.patch | 4.33 KB | ilo |
Comments
Comment #1
ilo commentedLet me take a look to the code. In the meantime I would like to know:
- have you cron enabled, and what is the frequency of cron execution?
- Had you tried more times to fail the login before enabling the delay?
The difference between beta and RC1 that may affect the delay is just a patch about cron cleaning functions: #499788: Time track depending on cron is not accurate.. I'll review it as soon as I can and submit a fix for you to test during the following hours..
Comment #2
ilo commentedJust one note.. (as in RC1)..
The delay is computed using the %user_ip_current_count variable, so the operation should not be affected when using other login name, or using a different IP address. I need you to check this to be able to find the problem. Also, it's not possible to have reached the max execution time of PHP (unless your site takes more than 3 seconds to complete a request).
Lastly, are you trying again and again from the same host? if all the testing request you are doing come from the same IP address, the tracking table would be full of login entries.. Do you have a very big tracking time value (of several hours maybe)? The code first remove pending events and then computes the delay.. waiting for the tracking time to pass would clean the table.
Hope this could also help us to find where the problem is, because I can't reproduce the problem..
Also.. are you using other login modules in these sites? (login destination?)
Comment #3
hd commentedThanks for the quick response.
Regarding #1:
It does not matter whether or not I have cron enabled.
I have tried several times to fail the login with bad passwords before enabling the delay. Does not make a difference.
Regarding #2:
It has not reached the max execution time of PHP.
I am not using other login modules.
I have been observing the tracking table.
What I found is that sleep is called with a negative value, when I enter the correct password. Always! When I enter a wrong password sleep is called with positive values increasing with each attempt.
This happens always, irrespective of already existing entries in table login_security_track. Whenever I enter the correct password, sleep is called with the negative value of the delay increase time, like -5 in my configuration.
The entries, if any, in table login_security_track are cleared, but it does not complete the login. In the Drupal log it even says "Session opened for ...." confirming a successful login.
Eventually I added a test before calling sleep to avoid negative values:
This fixed it, although it does not solve the underlying problem of calculating a negative value in the first place. Have not yet wrapped my mind around all the code in the module, but hope that this is of help. As already said, I experience this on two quite different Drupal 6.13 sites.
Notes:
When entering the wrong password, things work as expected, the delay is increasing and I am prompted again and again until having exhausted the number of allowed attempts.
Doing away with the error control character @ in front of sleep did not help in seeing sleep's error message in the log files (Drupal and Apache). It should produce something like "Warning: sleep(): Number of seconds must be greater than or equal to 0"
I am running PHP 4.3.9 (perhaps it behaves differently on PHP 5).
When I create an ordinary page, input format php, and add the following:
... and click on save, then the page is not being rendered, it just sits there. Clicking on view (because it has been saved), just shows a white browser screen. Basically it is exhibiting a similar behavior like when trying to login with a correct password, it just gets stuck without any error messages anywhere.
Comment #4
ilo commentedThanks a lot for the analysis Helmut. I did review a little few things to be sure you were completely right at all. I did a mistake not checking that secs could be negative.
In the patch I've included some validation functions to the settings form elements, and verified that sleep never gets a negative value again.. The patch is for DRUPAL-6--1 branch.
Comment #5
ilo commentedForget previous patch, allways delays (max_execution_time - 3). This one fixes that error..
Comment #6
ilo commentedI forgot to mention, with this change, the Delay base time is introduced in any login attempt. This could be a unexpected behaviour turning into a new feature, because we have already separated "login delay base time" and "Increase delay for each attempt". In the current implementation, the "login delay base time" is ignored if the "Increase delay" option is set to "No".
With this patch, every login attempt is delayed at least the "login delay base time" value in seconds, being harder for bruteforce attempts to guess passwords. So, to clarify, I would include in the documentation:
---
login delay base time: the value of this parameter sets the ammount of seconds a login attempt would take. This way, you may protect your site of bruteforce attacks making the process of guessing slow.
Increase delay for each attempt: If you want to make the password guessing even harder, you may increase the delay of the login operation for each new attempt, being computed in the form of....... bla bla bla..
---
This new alternative looks good for me.. I would like to hear also your opinions..
Comment #7
hd commentedI have applied the patch provided in #5 and it does fix the problem. Thanks.
Comment #8
hd commentedRegarding #6:
The patched version does not delay any successful logins when "Increase delay for each attempt" has been selected. It does, however, delay successful logins when option "Increase delay for each attempt" has NOT been selected (even if the successful login is not preceded by a failed login attempt).
With other words, the patched version works well when "Increase delay for each attempt" has been selected without showing any unexpected behavior. Only failed login attempts cause a delay (while using the same userID). At least, that is what I experience.
The unpatched (like the patched) version does delay successful logins when option "Increase delay for each attempt" has not been selected. Can't tell the behaviour of the unpatched version when "Increase delay for each attempt" has been selected, as it created negative sleep times.
Comment #9
ilo commentedI will wait a little for Deekayen to tell about the new "functionality" exposed by this patch before commiting. Thanks for testing.
Comment #10
ilo commentedSorry Helmut, I didn't notice this comment until now..
The patch at #6 includes the following lines for the Delay operation, I've commented a little bit:
"It does, however, delay successful logins when option "Increase delay for each attempt" has NOT been selected (even if the successful login is not preceded by a failed login attempt)."
This is the unexpected behaviour I was talking about.
We can make two fixes here:
1.- Avoid sleep when "Increase delay for each attempt" has not been set:
2.- DO sleep delay_base_time on any login attempt:
Assuming that "DELAY_BASE_TIME" was first defined only for delays, I would say 1 is the prefered option. But as we have two different configuration options (delay_base_time and delay_increase) I guess we can take profit of the first one to just settle a default login delay for any attempt. +1 extra feature against bruteforce attacks.
If you have any preference about which of the fixes apply please share..
Comment #11
ilo commentedCommited to 6.x-1.x-dev. Will be documented in README in the next commit.
Comment #12
hd commentedSorry, ilo, I have not followed this for a while.
I also think that option 1 should be the preferred option.
Comment #13
ilo commentedHi Helmut, this was already commited with the 2nd option as the winner. Only failed logins are punished with the delay base time, so it will not affect regular logins, while does protect the wrong login attempts with a little penalty to avoid password guessing operations.
So now, when delay base time has a value > 0, every invalid login is punished at least this ammount of seconds, and if "increase delay" is selected, the ammount will be multiplied by the number of invalid login attempts. This is the final behaviour of the delaying options.
I guess it's time to check also other changes in the module. I kindly suggest you to take a look at: http://drupal.org/node/397890#comment-2068410 and also review the new README file with updated instructions about the module, somethings have changed since your last comment in this issue.
Cheers!
ilo