Override Authlogic login error messages for better security
Authlogic is a cool plugin that handles authentication for Rails (and Merb, etc). But I just ran into a problem with one of its assumptions (which more generally probably ties back to a Rails assumption): one error == one field == one message.
However, when dealing with authentication and other security mechanisms, the less information you leak out, the better the security. So error messages that distinguish an invalid username from an incorrect password may be friendly, but they can let a would-be attacker gather more intel. Better to hide it all behind a general "Invalid login" message.
But how to do that without diving into Authlogic's nicely maintained internals? You could override error_messages_for, but that's overkill for this single case. Rails doesn't let you remove individual items from the errors object, which would solve this cleanly. So I hit upon this solution, which fits my need fine, but may not be the best for everyone.
I use Authlogic's validate callback to clear a login or password error and replace with my generic message.
class UserSession < Authlogic::Session::Base validate :generic_error def generic_error RAILS_DEFAULT_LOGGER.debug "checking errors ..." clear = false errors.each do |attr,message| puts "Error: #{attr.inspect}: #{message}" if ( (attr == 'login' and message == 'does not exist') or (attr == 'password' and message == 'is not valid') ) clear = true end end if clear RAILS_DEFAULT_LOGGER.debug "clearing errors ..." errors.clear errors.add_to_base("Invalid login credentials") end end end
Easy enough! Know a better solution? Let me know in the comments














Comments
http://authlogic.rubyforge.or
http://authlogic.rubyforge.org/classes/Authlogic/Session/Password/Config...
class UserSession < Authlogic::Session::Base
generalize_credentials_error_messages true
end
gives you message:
Login/Password combination is not valid
Wow, not sure how I missed
Wow, not sure how I missed that one. Thanks!!
The biggest issue I can see
The biggest issue I can see is that errors.clear will blow away any other errors.
You'd have to unload each error, save it, (rewrite the error if necessary) then reload them all (using errors.add / errors.add_to_base)
Post new comment