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
		if clear
			RAILS_DEFAULT_LOGGER.debug "clearing errors ..."
			errors.add_to_base("Invalid login credentials")

Easy enough! Know a better solution? Let me know in the comments


If you use

If you use 'generalize_credentials_error_messages true' you still end up with the error:
1 error prohibited this user session from being saved
There were problems with the following fields:
* Email/Password combination is not valid

The whole bit about the "user session" isn't very useful and likely to confuse the user. Also it requires work to alter.

I find it easiest to just do this in the view:
<% unless @user_session.valid? %>
Login was invalid
<% end %>



class UserSession < Authlogic::Session::Base
generalize_credentials_error_messages true

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

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <pre>, <shell>, <c>, <drupal6>, <java>, <javascript>, <objc>, <perl>, <php>, <python>, <rails>, <ruby>, <sql>, <xmlcode>. The supported tag styles are: <foo>, [foo].

More information about formatting options

This question is for testing whether you are a human visitor and to prevent automated spam submissions.