You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Marc Palmer <ma...@anyware.co.uk> on 2001/04/13 03:44:31 UTC

Auth bug in 3.2.1?

Hi,

I'm a relative tomcat newbie but have discovered what looks to me like a 
bug in the simple tomcat-user.xml authentication interceptor.

In a nutshell:

In tomcat-users.xml I have 2 users, in 2 different roles, let's say:

"john" has role "manager"
"jane" has role "clerk"

They auth fine, my servlet is protected using this scheme, everything is 
beautiful. 

However, when a (real life) user exits their browser (to clear auth 
credentials) and opens a browser again on the same PC and goes to my site 
and logs in as a different tomcat user, the user Principal remains the 
same as the previous request, but the role changes!

Step by step:

1) User logs in as "jane". Servlet prints "user = jane, role=clerk"

2) User closes and re-opens browser window.

3) User logs in again, this time as "john". Servlet prints "user = jane, 
role = manager".

So, basically getUserPrincipal is not changing, for some WEIRD reason. 
Role changes ok, so auth is happening, but it's like the auth interceptor 
is caching principals by IP or something.

AFAIK this is not a problem with the browser (IE5) because I have 
rebooted in between logins and the problem still occurs. In addition, 
keeping a second auth attempt (that shows incorrect user principal) open 
in the browser and restarting tomcat and then pressing REFRESH on the 
browser sends the CORRECT principal to my servlet – so it looks like the 
browser is sending the right credentials.

Am I being silly, or is this a boo-boo?

Cheers



Re: Auth bug in 3.2.1?

Posted by Marc Palmer <ma...@anyware.co.uk>.
>Hi Marc, 
>I saw this problem in 3.2.1 as well  - I made a fix for it in the tomcat 
that ships with the Borland AppServer >but 
>couldn't get anyone to comment on the fix in the main code-line 
(essentially I'm not a commiter so couldn't >submit the fix) 
Hi Thom,
Thanks for the info. Can someone from the Tomcat development team please 
comment on this? I would have thought that this was quite a serious 
security problem – am I wrong?
The way I see it, the bug could lead to anybody grabbing another user's 
role while appearing to be somebody else. This is certainly possible if 
you use somebody else's PC after they have. It may be even worse if you 
can also do this from a different PC – essentially getting a "random" 
role that somebody else already "provided" by logging in. Not to mention 
plain old failure in the case where a higher "privileged" person get's a 
lower privileged role allocated. It's not clear at this time whether the 
principal caching is tied to IP or "per pooled connection". If the 
latter, it's a bit more scary.
So once again, can someone from the Tomcat team PLEASE comment on this 
problem and whether a fix is being implemented? Perhaps there is too much 
work/redesign going on in 4.0 for people to consider patching 3.2.x but I 
would have thought this is pretty essential, and perhaps even merits a 
post to the BUGTRAQ mailing list. We already have 3 confirmed "sufferers" 
– who knows how many systems that depend on tomcat have slipped through 
the net and represent significant authentication breaches?

Cheers



Re: Auth bug in 3.2.1?

Posted by Thom Park <tp...@borland.com>.
Hi Marc,

I saw this problem in 3.2.1 as well  - I made a fix for it in the tomcat that
ships with the Borland AppServer but
couldn't get anyone to comment on the fix in the main code-line (essentially
I'm not a commiter so couldn't submit the fix)

Here's what I found:

The following code is in org.apache.tomcat.core.RequestImpl.java:

    public Principal getUserPrincipal() {
         if( getRemoteUser() == null ) return null;
         if( principal == null ) {
             principal=new SimplePrincipal( getRemoteUser() );
         }
         return principal;
    }

Notice the call to SimplePrincipal - this creates a new SimplePrincpal object
(i.e. a java.security.principal) using the
name associated with the remote User call.

I found two problems with this approach -

1. The username used was not that of the current user - it was of the
previously authorized user - subsequent users after the first one to be
authorized
    didn't get changed  the reason for this is that the only time we refresh
the principal with a new user, is if the principal was null, but, in this
case, it wasn't
    the principal still held the previous user's principal..

2. If you were using a custom Realm for authorization (e.g. LDAPRealm), then
this 'new' principal wouldn't be valid for that authorization object.
   If the servlet tried to use that 'special' principal for use with some
other software, it would no longer be the 'special' principal -it would be a
SimplePrincipal.


 It blew my J2EE CTS testing out of the water in several places.

I fixed it by doing the following:
1.  in org.apache.tomcat.core.RequestImpl.java: I made the following change
to getUserPrincipal:

    public Principal getUserPrincipal() {
         if( getRemoteUser() == null ) return null;
         // else return principal
         return principal;
    }

And in SimplRealm (and JDBCRealm and any other special Realm Manager) I added
the following to the authenticate method:
(in bold).  My rationale for making this change was that, given it was the
Realm manager's job to authenticate the user - and, only after authentication

should the userPrincipal be set, I moved the responsibility for setting the
UserPrincipal to the Realm manager.

This also meant that, at any time following successful authorization, the
current user principal would be correct for the user.

    public int authenticate( Request req, Response response )
    {
     // Extract the credentials
     Hashtable cred=new Hashtable();
     SecurityTools.credentials( req, cred );

     // This realm will use only username and password callbacks
     String user=(String)cred.get("username");
     String password=(String)cred.get("password");

     if( debug > 0 ) log( "Verify user=" + user + " pass=" + password );
     if( memoryRealm.checkPassword( user, password ) ) {
         if( debug > 0 ) log( "Auth ok, user=" + user );
             req.setRemoteUser( user );
            // set principal as well
            req.setUserPrincipal(new SimplePrincipal(user));
            Context ctx = req.getContext();
            if (ctx != null)
                req.setAuthType(ctx.getAuthMethod());
        }
         return 0;
    }

Anyway, that's the story behind this particular problem.

There's also a bug in support for security-role-links but that's another
story ;-)

-Thom


Marc Palmer wrote:

> Hi,
>
> I'm a relative tomcat newbie but have discovered what looks to me like a
> bug in the simple tomcat-user.xml authentication interceptor.
>
> In a nutshell:
>
> In tomcat-users.xml I have 2 users, in 2 different roles, let's say:
>
> "john" has role "manager"
> "jane" has role "clerk"
>
> They auth fine, my servlet is protected using this scheme, everything is
> beautiful.
>
> However, when a (real life) user exits their browser (to clear auth
> credentials) and opens a browser again on the same PC and goes to my site
> and logs in as a different tomcat user, the user Principal remains the
> same as the previous request, but the role changes!
>
> Step by step:
>
> 1) User logs in as "jane". Servlet prints "user = jane, role=clerk"
>
> 2) User closes and re-opens browser window.
>
> 3) User logs in again, this time as "john". Servlet prints "user = jane,
> role = manager".
>
> So, basically getUserPrincipal is not changing, for some WEIRD reason.
> Role changes ok, so auth is happening, but it's like the auth interceptor
> is caching principals by IP or something.
>
> AFAIK this is not a problem with the browser (IE5) because I have
> rebooted in between logins and the problem still occurs. In addition,
> keeping a second auth attempt (that shows incorrect user principal) open
> in the browser and restarting tomcat and then pressing REFRESH on the
> browser sends the CORRECT principal to my servlet – so it looks like the
> browser is sending the right credentials.
>
> Am I being silly, or is this a boo-boo?
>
> Cheers

--
http://www.borland.com/newsgroups
http://www.borland.com/devsupport/disclaim.html