tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject DO NOT REPLY [Bug 46902] LoginValve to bypass restrictions of j_security_check
Date Thu, 07 May 2009 11:16:21 GMT

--- Comment #3 from Gregor Schneider <>  2009-05-07 04:16:18 PST

On Thu, May 7, 2009 at 4:07 AM, Christopher Schultz
<> wrote:
> A few questions:
Chris, maybe you'll get the hang of this Valve if I explain the
business-requirement I had:

My primary target was to cirumvent the problem having a framed web-app, where
some content is requested after the session has timed out.

let's say we have the following website-structure:

| menue1 |                               |    
| menue2 |     some_content              |    
| menue3 |                               |    
| menue4 |                               |    
| menue5 |                               |    

(hope the formatting is ok )

"some_content" is an iframe, and the content of this iframe is changed by
selecting one of the left menue-items.
The iframe is specified in "index.html such as:

           <iframe name="some_content" src="/protected/somepage.html">
                    Some iframe-error-message

Now let's assume, session is timing out, and after that timeout the user
selects one of the menue-entries on the left side.
What's happening?

The url requested will look like "http://mysite/protected/some_stuff"

The HTML in that case looks like

<a href="http://mysite/protected/some_stuff.html"

Now this triggers j_security_check, but unfortunately j_security_check just
stores the last request, and after passing the credentials,
you'll won't see your "index.html" but "/protected/some_stuff.html" - without
the iframe and aboviously without the menue.

So the purpose of this Valve is to provide a mechanism which makes sure, that
if a non-authorized request comes in requesting anything else but your
"/protected/index.html", that the original request (i.e.
"/protected/some_stuff") is replaced by
"/protected/index.html" (or any other url being specified in the

Now take a look at some example-Valve-descriptor:

    <Valve  className="org.apache.catalina.valves.LoginValve"

This basically says, that all /non-authorized/ requests to the protected
content will be re-routed to "/protected/index.html" (redirectAfterAuth).

> 1. Why can't the "redirectAfterAuth" path be within the protected space?

Actually I do not see why this shouldn't be possible: Actually the idea is,
that redirectAfterAuth /must/ be in the protected area

If you take a look at the first condition:

if (aRequest.getRequestURI().startsWith(protectedPath)
    !aRequest.getRequestURI().startsWith("/j_security_check", 10)) {

Basically it says:

- Only URLs are handled being in my protected area
- the URL must /not/ be equal my default protected starting-URL
- the URL requested must /not/ be j_security_check

The two latter conditions are necessary to avoid an infinite loop when
accessing protected content

> 2. Why do you check to see if the request URI /startsWith/ the
>   redirectAfterAuth instead of being equal to it?

Because there might be some parameters after the adress in the URL - i.e., if
Cookies are not possible so that the session-information is stored within the

> 3. Why are you checking to see if characters 10 - 16 of the request URI
>   are "y_check". Why not check for the whole "j_security_check" string?
>   Why not check the /end/ of the request URI for j_security_check,
>   since the URI for j_security_check is not required to be
>   /j_security_check but pretty much */j_security_check?

You are right with this:

Actually I made a mistake here:

When "j_security_check" is triggered, the URL will look like


As you can see, in this example it works since "/protected" is exactly 10
characters long.

Therefore, the correct code would be 

    && !aRequest.getRequestURI().startsWith("/j_security_check"
        , protectedPath.length())) {

I'll correct that with a new patch during the weekend.

Why do I not ask for the String ending with "j_security_check"? 
I was not sure how that URL looks like if session-info is encoded within the
URL - therefore I'm using startsWith()

> 4. Why are killing the session if the authtype is null?

Because we experienced with some users, esp. behind company-proxies, that
situations may occur where a session still exists, but the Principal was null.
Therefore, if Principal is null, better be safe than sorry and make sure you
definately have a new session

> 5. Why does your valve pass-through any requests before the component
>   has "started"? Is there a valid use case where NOT performing these
>   checks and redirects is appropriate?

Nope. I took this code from AccessLogValve (I believe it was that one), and my
assumption was those checks don't make sense /before/ the Valve is completely
set (started).
If you feel that a different approach does make more sense here, I'm happy for
your suggestions

> It appears that your valve does nothing but murder the session and
> redirect the user if authtype=null and you are requesting a resource
> from a particular URI space. This does not seem particularly useful.
> Maybe I'm missing something subtle.

Seems to be - see my explanations on top.


Configure bugmail:
------- You are receiving this mail because: -------
You are the assignee for the bug.

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message