I have a Revo 2.3.3 site, is there a way to track failed logins?
Jim
Give a man the answer, and he’ll only have a temporary solution. Teach him the principles that led you to that answer, and he will be able to create his own solutions in the future.
The user detail includes a failed login count. If you want to generate a report on all failed logins across your user base you could write a small snippet that grabbed this info via the API. There isn't an out-of-the-box way addon for this sort of thing that I'm aware of.
If you're using Google Analytics (or any analytics that allows reporting of custom events) you could write some simple javascript to detect when the error message for a failed login is displayed and trigger a custom event in your analytics that could be used to generate a report.
Just a couple quick ideas, I'm sure there are other ways I'm not thinking of currently.
discuss.answer
If you want to log all failed login attempts, you'd have to create a plugin attached to OnBeforeWebLogin (and OnBeforeManagerLogin if you want manger logins as well).
In the plugin, $username and $password would be set to what the user entered. The code would look something like this (untested):
$loginUser = $modx->getObject('modUser', array('username' => $username));
if (! $loginUser) {
/* User not found, log info somewhere */
} else {
/* User Found, check password */
if (!$loginUser->passwordMatches($password)) {
/* Password is wrong - log info somewhere */
} else {
/* Login will be successful */
}
}
/* Make sure we don't interfere with the regular login process */
return true;
Thanks claytonk and Bob.
Bob, your suggestion is exactly the sort of thing I'm looking for. I was hoping for the lazy out-of-the-box option and find a quick and dirty extra but this is great.
I have a couple of users who insist they cannot log into our member's only area (despite the fact the login snippet has a friendly welcome back message). I want to see what they are or are not entering.
Jim
Give a man the answer, and he’ll only have a temporary solution. Teach him the principles that led you to that answer, and he will be able to create his own solutions in the future.
For a temporary situation like that, I usually use the error log (though it's not that difficult to append to a chunk's content).
$loginUser = $modx->getObject('modUser', array('username' => $username));
$msg = '';
if (! $loginUser) {
/* User not found, log info somewhere */
$msg = '[Login plugin] - User not found: ' . $username;
} else {
/* User Found, check password */
if (!$loginUser->passwordMatches($password)) {
/* Password is wrong - log info somewhere */
$msg = '[Login plugin] - invalid password: ' . $password . ' for user ' . $username;;
} else {
/* Login will be successful */
}
}
if (!empty($msg)) {
$modx->log(modX::LOG_LEVEL_ERROR, $msg);
}
/* Make sure we don't interfere with the regular login process */
return true;
Thanks Bob, I've implemented that. Hopefully we'll see what she is doing wrong.
Give a man the answer, and he’ll only have a temporary solution. Teach him the principles that led you to that answer, and he will be able to create his own solutions in the future.
I was writing a blog post on this and it occurred to me that the users' usernames and passwords will be in plain text in the log file. On many installations, it can be read by anyone with internet access by going to
http://yoursite.com/core/cache/logs/error.log.
You can protect against this by writing to a custom log file with code like this:
$log_target = array(
'target'=>'FILE',
'options' => array(
'filepath' => 'path/to/directory/',
'filename'=>'my_custom.log',
)
);
$modx->log(modX::LOG_LEVEL_ERROR, $msg, $log_target);
If you've moved your core above the web root, this is less of an issue. The filepath in the code above should end in a slash and it can be anywhere as long as the directory exists and is writable. I think this would work, but I haven't tested it:
'filepath' => MODX_CORE_PATH . '../../somedirectory/',
That should place the log file above the MODX web root. Another way would be to put it in a directory in the cache and protect that directory with an .htaccess file as described here:
http://davidwalsh.name/password-protect-directory-using-htaccess.
Good point. I'll remember that should I need to use the plugin again. Capturing the data in the error log helped us solve our problem which was not a username or password problem at all but a browser problem with the Login activation email message. Internet explorer was not handling the activation link properly and the user(s) thought they has a problem with their credentials (which I suppose in a way they did as they had not completed the activation). I have since changed the activation message to suggest that they copy and paste the activation link into the browser if they have problems.
Give a man the answer, and he’ll only have a temporary solution. Teach him the principles that led you to that answer, and he will be able to create his own solutions in the future.
-
☆ A M B ☆
- 427 Posts
The simplest way to protect against this is to modify the ht.access provided by the MODX installer in the core folder.
From:
IndexIgnore */*
<Files *.php>
Order Deny,Allow
Deny from all
</Files>
To:
IndexIgnore */*
<Files *.php>
Order Deny,Allow
Deny from all
</Files>
<Files *.log>
Order Deny,Allow
Deny from all
</Files>
And then rename it to .htaccess
Problem solved.
[ed. note: wshawn last edited this post 11 years, 6 months ago.]
That's a great solution.