Closed Bug 137852 Opened 22 years ago Closed 8 years ago

Basic HTTP AUTH using WWW-authenticate and 401 Unauthorized b0rked (ignores Realm, sends stale data)

Categories

(Core :: Networking, defect, P5)

x86
Linux
defect

Tracking

()

RESOLVED FIXED
mozilla47
Tracking Status
firefox47 --- fixed

People

(Reporter: ccurtis0, Assigned: andreaio.it)

References

Details

(Keywords: helpwanted, Whiteboard: [necko-active])

Attachments

(2 files, 1 obsolete file)

I've been working on a site that authenticates using Basic HTTP Auth.  It assigns a realm based on the current time, and sets the time in a cookie.  
At logout, the cookie is removed and a new realm is generated.  This works correctly with Konqueror, but Mozilla continues to send old data.

Here is the code in PHP (edited slightly):

----------------------------------------------------
$c = $HTTP_COOKIE_VARS["realm"];
fwrite( $fp, "Cookie: $c, User: $PHP_AUTH_USER, Pass: $PHP_AUTH_PW\n" );

// We must first declare what our realm should be
if( !($realm = $HTTP_COOKIE_VARS["realm"] ))
{	$realm = "License Admin - " . time();
	$HTTP_COOKIE_VARS["realm"] = $realm;
	Header( "WWW-authenticate: basic realm=\"$realm\"" ); 
	Header( "HTTP/1.0 401 Unauthorized" ); 
	SetCookie( "realm", $HTTP_COOKIE_VARS["realm"], time() + 3600 );

	// delete any stale info from the old realm
	$PHP_AUTH_USER = null;
}

// If we have not authenticated, ask for it
if( !$PHP_AUTH_USER )
{	Header( "WWW-authenticate: basic realm=\"$realm\"" ); 
	Header( "HTTP/1.0 401 Unauthorized" ); 
	echo "Text to see if user hits 'Cancel'"; 
	exit; 
} 

// Verify the password for the user
if( "passwd" != $PHP_AUTH_PW )
{	Header( "HTTP/1.0 401 Unauthorized" );
	Header( "WWW-authenticate: basic realm=\"$realm\"" ); 
	echo "Text to see if the password is incorrect<br>"; 
	exit;
}

// Auto-logout: 1 hour
SetCookie( "realm", $HTTP_COOKIE_VARS["realm"], time() + 3600 );
----------------------------------------------------

And here is the trace (mozilla 0.9.9; 20020411)

----------------------------------------------------
Cookie: , User: admin, Pass: passwd
Creating new realm: License Admin - 1019008891
Asking for a username/password
Cookie: License Admin - 1019008891, User: admin, Pass: passwd
Cookie: , User: admin, Pass: passwd
Creating new realm: License Admin - 1019008912
Asking for a username/password
Cookie: License Admin - 1019008912, User: sales, Pass: passwd
Cookie: License Admin - 1019008912, User: admin, Pass: passwd
----------------------------------------------------

What seems to happen is this:

I log in as "Admin".
I do whatever.
I select "Log out".
I try to log in again.
I am prompted for a username and password.
I log in as "Sales"
The next Authentication data is old ("Admin").

I was just changing the realm to force a logout, but Mozilla completely ignored this, which I why I made it more elaborate.  I'm not sure if the 
less elaborate way would have worked or not, because I assume that Mozilla would do the right thing.  After trying to debug my code and then 
creating the trace file, I decided to try Konqueror, which behaves as I would expect.  This leads me to believe that Mozilla is misbehaving.

I see no bug of this sort with bug 61681 - perhaps it should be added there too

Chris
there is no standard to indicate that a user-agent should delete all auth tokens
for a particular realm when an URL under that realm is newly challenged.

is it possible for you to provide a live testcase on the internet so that i can
be sure that i understand correctly the problem you are describing?
Severity: normal → minor
Unfortunately, the code is firewalled ... however, let me try to clear up a
little confusion:

The same URL under the same realm should give the same credentials.  Both IE and
NS4 delete these when the realm changes (according to my web research).  Then
supplying the original realm, the browers re-prompt for authorization.

However, here is what is happening here (activity interspersed):

Legend:
 [A]ction (taken by user)
 [L]ogs (recorded to file)
 [P]rogram logic
 [B]rowser responds

A: Visit URL
L: Cookie: , user=,pass=
P: No cookie, create "time realm"
L: Creating new realm
L: Prompt for Username/Password
P: Send "WWW-Authenticate" and "401 Unauthorized"
P: Set cookie with realm name in $realm (foo111)
B: Ask for Username and Password (1)
...
A: Enter Username and Password (credentials1)
B: Submit (credentials1) and session cookie
L: Realm = foo111, user=user1, pass=pass1
P: Allow access ... issue redirect (display page)
...
A: Logout
B: Submit (credentials1) and session cookie
L: Realm = foo111, user=user1, pass=pass1
P: remove cookie
...
A: Login again
L: Cookie: , user=user1,pass=pass1
P: No cookie, create "time realm 2"
L: Creating new realm
L: Prompt for Username/Password
P: Send "WWW-Authenticate" and "401 Unauthorized"
P: Set cookie with realm name in $realm (FOO222)
B: Ask for Username and Password
...
A: Enter Username and Password (Credentials_2)
B: Submit (Credentials_2) and session cookie
L: Realm = FOO222, user=User2, pass=Pass2
P: Allow access ... issue redirect
...
B: Load new page (based on redirect)
 ***
B: Submit (credentials1) and session cookie
L: Realm = FOO222, user=user1, pass=pass1
 ***

Notes (1):
  I don't know the spec, but "License Administration - <unixtime>" appears to
overflow a boundary (of about 30 characters) for the realm name.  This was the
first thing that I noted was broken with Mozilla.  It seems that this buffer
length should be expanded.

The credentials being passed are obviously wrong.  Whether you chose to delete
them at a realm change (as is the behavior of NS4, IE, etc) or not (like no
other) doesn't really change that there were new credentials submitted for a new
realm, and then not retained.  Not only were the old ones not deleted, they were
submitted for the wrong realm and in the stead of new ones!

My $0.02 is that this isn't really "minor", and apologies about the previous
word wrapping - Konqueror did it...
ah.. thanks for clarifying the bug.  i'll investigate this for mozilla 1.0.1.
Severity: minor → normal
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
Priority: -- → P3
Target Milestone: --- → mozilla1.0.1
I have a related problem when using lovely lovely MS Exchange server.  Again we
have both HTTP Basic auth and a session cookie.

Process is as follows:

Go to log in page, enter username (say, UserA), and the browser submits the form
sending:

==> GET /exchange/LogonFrm.asp?isnewwindow=0&mailbox=UserA HTTP/1.1

<== HTTP/1.1 401 Unauthorized
<== WWW-Authenticate: Basic realm="servername"

User is prompted for Basic auth details, browser retries and everything is fine.

User logs out and tries to re-login as UserB - different query string - sending
the auth and cookie data from the previous session.

==> GET /exchange/LogonFrm.asp?isnewwindow=0&mailbox=UserB HTTP/1.1
==> Authorization: Basic UserACypherText
==> Cookie: ASPSESSIONOLD=USELESSOLDDATA

<== HTTP/1.1 401 Unauthorized

<== WWW-Authenticate: Basic realm="servername"


At this point the browser should prompt the user to enter (or select) a new set
of authentication credentials.  Instead it repeats its previous request, which
puts Exchange in a huff and 302s you to an error page.

I've come back to Mozilla (presently testing with 2002042221 on RedHat 7.2)
after a spell with NS6.2 because 6.2.2 is unstable on my system.  I'm therefore
not sure when this problem was introduced.  Sorry.
Target Milestone: mozilla1.0.1 → ---
mass futuring of untargeted bugs
Target Milestone: --- → Future
related to bug 140645 ??
Blocks: 140645
Blocks: 143575
Blocks: 201620
has anyone given mozilla 1.4 beta a try?  many things have improved in the HTTP
auth implementation, so perhaps this bug has been fixed?  can someone please
test? thx!!
using firefox 0.9, http basic auth still doesn't work.

I navigate to my web app, the auth dialog come up, enter a bad user/password on
purpose, close the browser.
go to my web app again, anf the auth dialog don't show up, firefox insist in
using the cached user/password, then you are lost.

this is preventing the use of firefox/mozilla in my organization, we must use IE.
Hi Sergio, does the same problem happen if you try Mozilla-1.7rc3?
Priority: P3 → --
Target Milestone: Future → ---
hi darin, ok downloaded mozilla 1.7rc3 and no, mozilla is not sending cached
data after closing the browser.
I close the browser, open again and mozilla pop-up the passwd dialog again.

(I still prefer the IE behavior that do not need to close the browser if I
failed the login, ie: the httpd send the 401 code and www-authenticate code
again and IE pop-up the dialog again, but mozilla 1.7rc3 is a step ahead)

thanks!
> (I still prefer the IE behavior that do not need to close the browser if I
> failed the login, ie: the httpd send the 401 code and www-authenticate code
> again and IE pop-up the dialog again, but mozilla 1.7rc3 is a step ahead)

Are you sure Mozilla does not do this?  Can you provide a simple testcase or at
least provide a HTTP log file generated using instructions here:

  http://www.mozilla.org/projects/netlib/http/http-debugging.html

The log file should not include any passwords or usernames or even any base64
encoded usernames and passwords.  We try to keep the log file clean of that
stuff so folks like yourself will not feel hesistant to upload a log file. 
There's much I can learn about Mozilla's behavior from reading the log file.

Thanks!
yup, pretty sure...
test case: http://www.kessler.com.ar/http_basic_auth/
hmmm, after a while mozilla also start to send cached data...  :/

two different examples:

http://www.kessler.com.ar/http_basic_auth/index.php
http://www.kessler.com.ar/http_basic_auth/index2.php

use username 'foobar' on the second example and see the difference with IE.

thanks for the testcases... i hope to have time to investigate and fix this for
1.8a2.
Target Milestone: --- → mozilla1.8alpha2
This bug still exists in my local Mozilla (Debian 1.6-5).  I think what Sergio
is describing is a different bug.  I've reduced the test case to something more
useful, but I still don't have a place to post it.

Here is the PHP code:

----- 8< ----- 8< -----
<?php
$realm = $HTTP_COOKIE_VARS["realm"];

if( $_GET["logout"] == $realm || !$PHP_AUTH_USER )
{       Header( "HTTP/1.0 401 Unauthorized" );
        $realm = "License Admin - " . time();
        $HTTP_COOKIE_VARS["realm"] = $realm;
        SetCookie( "realm", $realm, time() + 3600 );
        Header( "WWW-authenticate: Basic realm=\"$realm\"" );
}

?>

<p>Welcome to realm <b><?= $realm ?></b>, <?= $PHP_AUTH_USER ?></p>
<a href="?logout=<?= $realm ?>">Retry</a>
----- 8< ----- 8< -----

Here is the scenario:

Load the given page, enter 'user1' as the username.  Output:

Welcome to realm License Admin - 1087577080, user1

Click the 'Retry' link, enter 'user2' as the username.  Output:

Welcome to realm License Admin - 1087577301, user2

Click 'Reload' on your browser.  Output:

Welcome to realm License Admin - 1087577301, user1

I hope this makes this original bug clearer.  user2 just logged in, but the
authentication token is now for user1.  I find it surprising this hasn't caused
numerous problems at public terminals, though maybe they all just run IE for
reasons like this.  This seemed a pretty important bug when I submitted it over
2 years ago, but I could be the only person in the world doing stupid things
with basic authentication.
created
http://www.kessler.com.ar/http_basic_auth/index3.php
with the code posted from Christopher...

and yes, my bug is better described at
http://bugzilla.mozilla.org/show_bug.cgi?id=201620
(which seems resolved in mozilla but not firefox)
Hi Sergio,

Thanks for posting that code.  Unfortunately, PHP doesn't seem to be installed
on that server, so it just shows up as plain text.  :(
oops, sorry...
can you try again ?
Looks like I posted broken code.  Will try to fix, may take a couple weeks.  :(
Target Milestone: mozilla1.8alpha2 → mozilla1.8beta
I'd love it if Mozilla sent the Basic Auth header when given in the URL
_without_ round tripping to the server first.  The initial request should have
the basic authorization, also, the password should be opttional (assumed to be
the empty string).  

I use 2-3 differnet authentication mechanisms.  If the user uses username@server,
I use digest over https, otherwise I use a completely different mechanism.  This
would give me a nice way to 'check' if regular http authentication shoudl be
used.  When my server gets a 'basic' authorization, it would then respond with
the digest message; lacking the basic authorizaiotn, it'd redirect to our
central-login-pain-in-the-**** thingy.
I don't expect to have time to get to this for Gecko 1.8 (Firefox 1.1).  Help
wanted.
Keywords: helpwanted
Priority: -- → P5
Target Milestone: mozilla1.8beta1 → mozilla1.8beta2
Target Milestone: mozilla1.8beta2 → mozilla1.9alpha
-> default owner
Assignee: darin → nobody
Status: ASSIGNED → NEW
Component: Networking: HTTP → Networking
QA Contact: tever → networking
Target Milestone: mozilla1.9alpha → ---
Attached file Test code (in PHP)
PHP has changed a bit in the past 12 years, updated example code to reflect these changes. Problem persists into FireFox 29.
Summary: Basic HTTP AUTH b0rked (ignores Realm, sends stale data) → Basic HTTP AUTH using WWW-authenticate and 401 Unauthorized b0rked (ignores Realm, sends stale data)
Assignee: nobody → andreaio.it
Still persists in 31.0.
Attachment #8475262 - Flags: review?(michal.novotny) → review?(jduell.mcbugs)
Comment on attachment 8475262 [details] [diff] [review]
Bug 137852 - The identity is now inserted at the beginning of the list and not appended so the last change is the first of the list

Review of attachment 8475262 [details] [diff] [review]:
-----------------------------------------------------------------

Honza do you know this code?  It's a one-line patch.
Attachment #8475262 - Flags: review?(jduell.mcbugs) → review?(honzab.moz)
Andrea, can you please provide few words on why you've decided that this is the fix?  Is there a test?  Automated, or at least for now a public test case?  We cannot take just a line of change without any words of explanation, test, or at least a comment in the patch.

Thanks!
Flags: needinfo?(andreaio.it)
Comment on attachment 8475262 [details] [diff] [review]
Bug 137852 - The identity is now inserted at the beginning of the list and not appended so the last change is the first of the list

Dropping r? until more info on the patch provided.
Attachment #8475262 - Flags: review?(honzab.moz)
I changed the line of code that adds the entry to the list of valid entries (mlist). When the user refreshes the page all the entries from the list are tried (starting from the first) and the first correct is used. The old code appended the new right entry and so the old one was tried first. You can test this using the code in the attachment 8428336 [details] (http://bookmod.altervista.org/firefox/bug137852.php).
Flags: needinfo?(andreaio.it)
comment 30
Flags: needinfo?(honzab.moz)
This problem seems to be worse if the two realms are parent and child. In fact, since I changed my website so the two folders with the two different realms were siblings it hasn't occurred to me again...

FWIW, it always worked OK with IE, not that that's a solution I would recommend of course :-)
So, first I'm really sorry this has been lost from my radar!  I was somehow hoping you will ask for r again on the patch after the info is provided.

I think the fix makes sense.  Something in my guts tells me tho there could be some security problem, but I cannot identify it.  Maybe it's just me being too cautious.

I'll update/submit/check in the patch.
Flags: needinfo?(honzab.moz)
I've added a comment why we do this.

https://treeherder.mozilla.org/#/jobs?repo=try&revision=66791aad5ff7
Attachment #8475262 - Attachment is obsolete: true
Attachment #8710607 - Flags: review+
Status: NEW → ASSIGNED
Whiteboard: [necko-active]
https://hg.mozilla.org/mozilla-central/rev/6801dfbc6119
Status: ASSIGNED → RESOLVED
Closed: 8 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla47
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: