That would be incredibly simple. You could also log the attempted password value. Modify your login function somehow, depending on your language.
Keep in mind, this is untested pseudo code, but the concept will work:
Couple of security things:
private boolean properLength(String u, String p)
{
return ((u.length > 3 && u.length <= 12) && (p.length > 8 && p.length <= 30)) ? true : false;
}
private boolean properFormat(String u, String p)
{
return (regex.Valid(u, usernameRegex) && regex.Valid(p, passwordRegex)) ? true : false;
}
private String stripBadStuff(String stuff)
{
// Just in case or something...
return EncodingFunction.ToASCII(stuff).regexReplace(badCharacaterRegex, "");
}
And the login:
public String login(String user, String pass)
{
if (!loginTriesExceeded) // Currently unhandled for example.
{
if ((user != null && pass != null) && properLength(user, pass) && properFormat(user, pass))
{
if (!userLoginTriesExceeded)
{
// Strips potential hacker injection attempts. You may want to find another way to log this attempt. You wouldn't want to log this to a database without parameters/bound variables. That's beyond the scope of this answer. Google it.
String newUser = stripBadStuff(user);
String newPass = stripBadStuff(pass);
// Would be changing DB.lookup() to return true if valid login is detected. DB.lookup(newUser,newPass) will now be assumed that it tests the plaintext password against the salted hash.
if (DB.lookup(newUser, newPass))
{
// Prevent injection. This will assume DB.lookup() tests the password against the stored hash.
return "Hello " + newUser;
}
else
{
logInvalidAttempt(newUser, newPass);
return "Invalid login.";
}
}
else
{
return "User login attempts exceeded.";
}
}
else
{
return "Invalid login.";
}
}
else
{
// Do nothing, or inform the visitor that they've exceeded max global logins based on their IP / cookie
return null;
}
}
You would just use logInvalidAttempt(user, pass);
when it fails. So instead of just saying, "login failed," you'd say "login failed" and log the attempt, but be careful not to implement any security flaws with this. You will have to ensure that the data is correctly input.
In general, just sanitizing input is not the answer, but I sometimes add it as an additional layer after everything else has finished, just in case. Not always, just sometimes. The example here is for learning purposes.
Keep in mind that you'll have to write your own logInvalidAttempt()
function; that is too broad for this answer.
You can also do this for any Content Management System
such as joomla
, WordPress
, Drupal
, Django
, et al. They are, after all, open source. So all you need to do is modify the appropriate login function.
You need to also make sure not too much data gets logged. You'll have to cut it off at some point.
TLDR:
- Modify login() function.
- When the user tries to log in using invalid credentials, log it somewhere.
- If logging to a SQL Server database, parameterize your queries.
- If logging to an Oracle database, bind your variables and use prepared statements.
- If logging to a MySQL database, use prepared statements and bind your parameters.
- If logging it to a file, or to any database, don't allow it to insert too much data. You gotta cut it off at some point.
- Read logs/database.