# HTTP Basic Authentication permitting wrong passwords through

**URL:** <https://www.ruby-forum.com/t/http-basic-authentication-permitting-wrong-passwords-through/158034>\
**Category:** Rails\
**Created:** [January 18, 2009, 6:46am UTC](https://www.ruby-forum.com/t/http-basic-authentication-permitting-wrong-passwords-through/158034 "2009-01-18T06:46:11Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jimmyether](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e9a140/32.png) [@jimmyether](https://www.ruby-forum.com/u/jimmyether)\
**Post date:** [January 18, 2009, 6:46am UTC](https://www.ruby-forum.com/t/http-basic-authentication-permitting-wrong-passwords-through/158034/1 "2009-01-18T06:46:11Z")

</div>

I’ve run into a strange problem with HTTP Basic authentication. I’ve  
observed this behavior on my dev box (connecting directly to mongrel)  
and on an Apache+Passenger setup on my deployment machine.

I’m doing the standard thing according to the semi-holy trinity of  
http\_authentication.rb on github, Railscast #82, and  
every-blog-tutorial-on-the-net: in my controller I have:

class CongsController \< ApplicationController  
before\_filter :authenticate, :only =\> [:edit, :delete, :update]

…

private

def authenticate  
authenticate\_or\_request\_with\_http\_basic do |username, password|  
username == ‘fred’ && password == ‘sekr3t’  
end  
end  
end

Sure enough, attempts to edit, update, or delete bring up the HTTP  
basic dialog in the browser, and I have to enter a name and password.  
If I enter them correctly, it passes me through properly.

The problem it also lets me through no matter WHAT I enter, right or  
wrong.

This is what I see this in the Rails log file:

Processing CongsController#edit (for 127.0.0.1 at 2009-01-17 23:25:27)  
[GET]  
Parameters: {“id”=\>“1276”}  
SQL (0.1ms) SET SQL\_AUTO\_IS\_NULL=0  
Filter chain halted as [:authenticate] rendered\_or\_redirected.  
Completed in 0ms (View: 0, DB: 0) | 401 Unauthorized  
[[http://localhost/congs/1276/edit](http://localhost/congs/1276/edit)]

Processing CongsController#edit (for 127.0.0.1 at 2009-01-17 23:25:30)  
[GET]  
Parameters: {“id”=\>“1276”}  
SQL (0.1ms) SET SQL\_AUTO\_IS\_NULL=0  
Cong Columns (4.6ms) SHOW FIELDS FROM `congs`  
Cong Load (15.0ms) SELECT \* FROM `congs` WHERE (`congs`.`id` =  
1276)  
Rendering congs/edit  
Completed in 36ms (View: 7, DB: 20) | 200 OK  
[[http://localhost/congs/1276/edit](http://localhost/congs/1276/edit)]

I can make it simpler yet: I can use this #authenticate method, and  
it still lets me through:

def authenticate  
return false;  
end

My project’s script/about says this:

Mac:~/src/rails/coc(master)\> script/about  
About your application’s environment  
Ruby version 1.8.6 (i686-darwin8.8.2)  
RubyGems version 1.3.1  
Rails version 2.2.2  
Active Record version 2.2.2  
Action Pack version 2.2.2  
Active Resource version 2.2.2  
Action Mailer version 2.2.2  
Active Support version 2.2.2  
Application root /Users/rew/src/rails/coc  
Environment development  
Database adapter mysql  
Database schema version 20090114205156

This is a VERY simple app; no tricky stuff going on, just a basic CRUD  
thing with a couple of models. I have no idea what is going on here.

Anybody know what I’m doing wrong here? Ideas or suggestions?

–  
Ryan W. ||| [http://www.erebor.com](http://www.erebor.com) ||| removed\_email\_address@domain.invalid

“The web goes ever, ever on, down from the site where it began…”

---

<div class="post-metadata">

**Author:** ![jimmyether](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e9a140/32.png) [@jimmyether](https://www.ruby-forum.com/u/jimmyether)\
**Post date:** [January 19, 2009, 2:26am UTC](https://www.ruby-forum.com/t/http-basic-authentication-permitting-wrong-passwords-through/158034/2 "2009-01-19T02:26:12Z")

</div>

On Sun, Jan 18, 2009 at 12:45 AM, Ryan W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> before\_filter :authenticate, :only =\> [:edit, :delete, :update]  
> end  
> Processing CongsController#edit (for 127.0.0.1 at 2009-01-17 23:25:27)  
> SQL (0.1ms) SET SQL\_AUTO\_IS\_NULL=0  
> def authenticate  
> Active Record version 2.2.2  
> thing with a couple of models. I have no idea what is going on here.
> 
> Anybody know what I’m doing wrong here? Ideas or suggestions?
> 
> According to the documentation (see e.g.  
> [http://www.railsbrain.com/api/rails-2.2.2/doc/index.html?a=C00000133&name=ClassMethods](http://www.railsbrain.com/api/rails-2.2.2/doc/index.html?a=C00000133&name=ClassMethods))  
> if a #before\_filter renders or redirects, the second half of an around  
> filter, and any after filters won’t run. I believe that you need to  
> redirect your unauthenticated user to some other page (such as your  
> login  
> page) if the authentication fails.

I thought I had read somewhere (perhaps in a book someplace) that if a  
filter returns false, it simply skips the rest of the processing in the  
filter chain – but I don’t see that in the documentation for filters.  
Perhaps it is just well known lore. (Or, perhaps, it’s something I just  
made up ;-). Regardless, if you think about what’s going in the  
#before\_filter chain, it’s just a bunch of processing that get’s called  
prior to calling your action method. If you want that processing to  
redirect the user somewhere else, then you need to explicitly put that  
in  
your processing. If you don’t put a specific redirect in your  
processing,  
how would Rails know if and to where it should redirect?

In my (one and only) application, I have

before\_filter :login\_required

#login\_required is provided by the authenticated system plugin and looks  
like

```
def login_required
  authorized? || access_denied
end

```

My particular version of #access\_denied looks like:

def access\_denied  
respond\_to do |format|  
format.html do  
flash[:notice] = “You must log in first”  
store\_location  
redirect\_to root\_path  
end  
format.any do  
request\_http\_basic\_authentication ‘Web Password’  
end  
end  
end

hope this helps a little…

–wpd

---

<div class="post-metadata">

**Author:** ![jimmyether](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e9a140/32.png) [@jimmyether](https://www.ruby-forum.com/u/jimmyether)\
**Post date:** [January 19, 2009, 7:50am UTC](https://www.ruby-forum.com/t/http-basic-authentication-permitting-wrong-passwords-through/158034/3 "2009-01-19T07:50:17Z")

</div>

Hey, Patrick! Thanks for the reply.

On Sun, Jan 18, 2009 at 7:25 PM, Patrick D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> On Sun, Jan 18, 2009 at 12:45 AM, Ryan W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > I’ve run into a strange problem with HTTP Basic authentication. I’ve  
> > observed this behavior on my dev box (connecting directly to mongrel)  
> > and on an Apache+Passenger setup on my deployment machine.

> According to the documentation (see e.g.  
> [http://www.railsbrain.com/api/rails-2.2.2/doc/index.html?a=C00000133&name=ClassMethods](http://www.railsbrain.com/api/rails-2.2.2/doc/index.html?a=C00000133&name=ClassMethods))  
> if a #before\_filter renders or redirects, the second half of an around  
> filter, and any after filters won’t run. I believe that you need to  
> redirect your unauthenticated user to some other page (such as your login  
> page) if the authentication fails.

That may be true, but that’s not how I understand it’s supposed to work.  
If  
authorization fails, then authenticate\_or\_request\_with\_basic\_http is  
supposed to render a 401 (I believe) with this message:

```
    controller. __send__ :render, :text => "HTTP Basic: Access

```

denied.\n", :status =\> :unauthorized

So the controller knows where to redirect to by virtue of it being  
hardcoded.

And the Rails documentation, as well as every other place I’ve seen  
showing  
how this works has it pretty much just like I have it.

I’ve either got a typo that I can’t find, or have set something up  
screwy in  
my app configuration, or something. I don’t _think_ that it’s because  
I’m  
supposed to explicitly redirect unauthorized users elsewhere. But I  
could  
be wrong.

Keep in mind that I’m not trying to build a full user-based auth system;  
I  
just want HTTP basic user/pass protection for a few actions in a single  
controller, just to help discourage the curious. So I’m not using any  
of  
the auth plugins or full-blown user login schemes available.

Am I missing something?

---

<div class="post-metadata">

**Author:** ![jimmyether](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e9a140/32.png) [@jimmyether](https://www.ruby-forum.com/u/jimmyether)\
**Post date:** [January 22, 2009, 5:52pm UTC](https://www.ruby-forum.com/t/http-basic-authentication-permitting-wrong-passwords-through/158034/4 "2009-01-22T17:52:50Z")

</div>

OK, in the spirit of full disclosure (not that anyone cares), I’ll admit  
my  
boneheadedness here. I HAD a problem the first time I tried the  
authentication in the standard way:

def authenticate  
authenticate\_or\_request\_with\_http\_basic do |username, password|  
username == ‘fred’ && password == ‘sekr3t’  
end  
end

But it wasn’t with the authenticate method. By this point, I have no  
idea  
what was wrong initially. But what I had actually done was something  
like:

def authenticate  
authenticate\_or\_request\_with\_http\_basic do |username, password|  
if (username == ‘fred’ && password == ‘sekr3t’)  
logger.info(“Passed with username: #{username} password:  
#{password}”)  
return true;  
else  
logger.info(“Failed with username: #{username} password:  
#{password}”)  
return false;  
end  
end  
end

Oops. Of course, you don’t ‘return’ values for a block. Duh. I knew  
that,  
but just didn’t see it for a day or so because I was looking for  
something  
deeper and less stupid.

Ah, well. Maybe I won’t forget this for a while. On the plus side, I  
got  
to walk through how before\_filters are called using ruby-debug.

New knowledge FTW!
