You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Erik Price <ep...@ptc.com> on 2003/01/24 18:52:25 UTC

INSECURE to rely on sendRedirect (??)

A few weeks ago I posted a question on this list asking if using 
response.sendRedirect() is a secure means of preventing a user agent 
from accessing content.  (For instance, in a scenario where, to access 
the content, the session is consulted for a key of some sort.  If the 
key is found, continue, otherwise a sendRedirect() is used to send the 
user to an error page.)

Since a redirect is performed using an HTTP header (rather than at the 
server, like RequestDispatcher.forward()), the user agent is not 
*obligated* to respect the redirect.  This means that relying on a 
redirect to protect secure data might be a mistake.  In other server 
side languages (Perl, PHP), you can call exit immediately after setting 
the header to ensure that the sensitive data is not sent from the server 
to the user agent in the event that the user agent does not respect the 
redirect.  However, as Paul Yunusov on this list pointed out to me, you 
cannot simply exit a servlet, it is not the same as a PHP or Perl 
script.  (The original message is appended to this one.)

The servlet spec says that further output should not be sent from a 
servlet that has called response.sendRedirect(), which means that in 
theory the sensitive data is protected.  However, I have run into a case 
where sendRedirect() does *not* prevent a request from being made to a JSP:

I am running Tomcat 4.0.6 and have a Filter named SecurityFilter mapped 
to a JSP named "main.jsp".  SecurityFilter consults the session for a 
key that is set when a user successfully passes through a login system. 
  If the key is present, then the Filter does nothing and the "main.jsp" 
page is served to the user.  However, if the key is not present, the 
Filter calls response.sendRedirect() to send the user to the login page. 
  In my case, "main.jsp" retrieves a bean from the session with the 
<jsp:useBean> tag.

THE PROBLEM:  When a user who has not yet started a session and 
registered the bean that "main.jsp" is looking for attempts to request 
"main.jsp", SecurityFilter should redirect the user to the login page. 
However, what actually happens is that for some reason the redirect is 
not happening immediately when it is called, and the Filter calling 
doFilterChain(), which means "main.jsp", which means that the JSP throws 
an exception because it cannot find the bean in the session.

Summary:

1) Calling sendRedirect() from a Filter does not happen before the 
Filter calls its doFilterChain() method
2) This means relying on sendRedirect() to protect sensitive data is 
probably not safe.

There could be a flaw in my logic, or I could simply be stating the 
obvious and everyone knew this.  If either of those is the case, please 
point out my fallacy and I apologize for wasting everyone's time. :)


Erik

PS: to correct my situation, should I just not call doFilterChain() in 
my Filter if the login key is not found?  Or would that violate the 
Filter spec....?



Paul Yunusov wrote:
> On Friday 10 January 2003 03:42 pm, Erik Price wrote:
> 
>>Paul Yunusov wrote:
>>
>>>sendRedirect() in HttpServletResponse will send an HTTP redirect response
>>>to the client so the client's browser itself makes a new request to the
>>>new URL (main.jsp in your case). It results in the new URL being shown in
>>>the browser's address field.
>>
>>Paul, this is exactly what I was looking for!  Thank you.  My only fear
>>is that if the client User Agent doesn't respect the HTTP Redirect (say
>>it is a malicious Perl script or something), does the servlet know not
>>to transmit any further data?  Or should I manually call System.exit()
>>after the response.sendRedirect() call?
> 
> 
> 
> Well, the API docs say "After using this method, the response should be 
> considered to be committed and should not be written to" so I guess the 
> developer rather than the servlet should know not to transmit any further 
> data from the servlet.
> 
> Definitely no System.exit() in servlets as that would theoretically attempt to 
> shut down the Tomcat process itself but I don't know anything about any 
> practical repercussions. You could try that and let us know what happened. 
> :-)
> 
> 
> 
>>>Note that the original request's parameters, which were sent to the
>>>servlet, are lost but check the sendRedirect()'s documentation for more
>>>details.
>>
>>That is okay, I will be storing data in the session in the LoginServlet
>>so the original parameters can be dropped.  Thank you very much again.
> 
> 
> Yes, holding the data in the session is what I thought you'd do, and I am glad 
> I could be of any help.
> 
> 
>>
>>Erik
> 
> 
> Paul
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
> 
> 


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: INSECURE to rely on sendRedirect (??)

Posted by Erik Price <ep...@ptc.com>.

Mike Jackson wrote:
> There's always something that can be done to make systems more secure, but
> you
> realistically need to balance the time and effort (both to secure it and to
> use it),
> with the environment.  My systems typically are installed on secure networks
> where
> all users are given fairly intense background checks.  So my balance is more
> towards
> the ease of use for the end user.

Agreed.  I'm pretty satisfied with the SecurityFilter so I'm going to 
shelve that for now and get to work on the main problem domain of my 
application for now.  Fortunately this is going to be a relatively 
low-traffic application, and it'll only be accessible from within our 
intranet, so security is not a huge concern.

Erik


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: INSECURE to rely on sendRedirect (??)

Posted by Mike Jackson <mj...@cdi-hq.com>.
They can't.  There's a mapping between the thing they're requesting and the
model
or models that are being called, you can't access the model directly.  You
could
access the page directly, but in most cases that won't get you anywhere, and
any
of the links that it points are directly controlled by the controller again,
so...

Really the only thing that's available that would allow you to bypass things
to any
level is the XSQL and XSL files I'm using to query the database, but I don't
pass
the XSQL mapping through apache to tomcat, you'd be getting the XSQL and XSL
files
as flat files rather than as the processed versions of those.  I could block
that in
apache, but as the XSQL files aren't in the same path as the page request
it'd be
a little hard to figure out where they are (and it lets me look at them
quickly if
I'm trying to diagnose something).

There's always something that can be done to make systems more secure, but
you
realistically need to balance the time and effort (both to secure it and to
use it),
with the environment.  My systems typically are installed on secure networks
where
all users are given fairly intense background checks.  So my balance is more
towards
the ease of use for the end user.

--mikej
-=-----
mike jackson
mjackson@cdi-hq.com

> -----Original Message-----
> From: Erik Price [mailto:eprice@ptc.com]
> Sent: Friday, January 24, 2003 10:28 AM
> To: Tomcat Users List
> Subject: Re: INSECURE to rely on sendRedirect (??)
>
>
>
>
> Mike Jackson wrote:
> > Actually I use a MVC architecture, my controller has a
> "standard" model for
> > doing logins.  So I just change the look for the login page and
> change the
> > configuration file a little and I'm done.  Nearly 100% code
> reuse (if you
> > consider the relatively static login page to be code).  Since
> my system is
> > fast and easy I haven't seen the need to branch out into new things yet.
>
> What happens if someone requests one of your resources directly?
>
> Also, I hear you -- I wasn't going to get into Filters but I read a bit
> about them and the idea is actually pretty simple.  And it seemed
> perfect for this situation, so I just tried it.  I'm pleased.
>
>
> Erik
>
>
> --
> To unsubscribe, e-mail:
<ma...@jakarta.apache.org>
For additional commands, e-mail:
<ma...@jakarta.apache.org>



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: INSECURE to rely on sendRedirect (??)

Posted by Erik Price <ep...@ptc.com>.

Mike Jackson wrote:
> Actually I use a MVC architecture, my controller has a "standard" model for
> doing logins.  So I just change the look for the login page and change the
> configuration file a little and I'm done.  Nearly 100% code reuse (if you
> consider the relatively static login page to be code).  Since my system is
> fast and easy I haven't seen the need to branch out into new things yet.

What happens if someone requests one of your resources directly?

Also, I hear you -- I wasn't going to get into Filters but I read a bit 
about them and the idea is actually pretty simple.  And it seemed 
perfect for this situation, so I just tried it.  I'm pleased.


Erik


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: INSECURE to rely on sendRedirect (??)

Posted by Mike Jackson <mj...@cdi-hq.com>.
Actually I use a MVC architecture, my controller has a "standard" model for
doing logins.  So I just change the look for the login page and change the
configuration file a little and I'm done.  Nearly 100% code reuse (if you
consider the relatively static login page to be code).  Since my system is
fast and easy I haven't seen the need to branch out into new things yet.

--mikej
-=-----
mike jackson
mjackson@cdi-hq.com

> -----Original Message-----
> From: Erik Price [mailto:eprice@ptc.com]
> Sent: Friday, January 24, 2003 10:20 AM
> To: Tomcat Users List
> Subject: Re: INSECURE to rely on sendRedirect (??)
>
>
>
>
> Mike Jackson wrote:
>
> >
> > So, in the end, I'm not clear on how filters work exactly
> (haven't needed to
> > use them yet), but when you're using the header type redirect
> you need to
> > make sure that you're not going to send back anything other than the
> > redirect.  If you do send something most clients will work properly, but
> > some won't.
> >
>
> Filters are like mini-servlets sort of, but they intercept a request for
> a resource and do something before passing the request along to the
> resource.  In my case, I wanted to call sendRedirect() from the filter,
> but it looks like that doesn't happen fast enough.  Using a return
> statement to terminate the doFilter() method call before it calls
> doFilterChain() seems to work though, as suggested by Tim Moore.
>
> The nice thing about a Filter is you can have one Filter mapped to every
> resource in the site, I'm not sure how you could get that with a regular
> servlet...
>
>
> Erik
>
>
> --
> To unsubscribe, e-mail:
<ma...@jakarta.apache.org>
For additional commands, e-mail:
<ma...@jakarta.apache.org>



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: INSECURE to rely on sendRedirect (??)

Posted by Erik Price <ep...@ptc.com>.

Mike Jackson wrote:

> 
> So, in the end, I'm not clear on how filters work exactly (haven't needed to
> use them yet), but when you're using the header type redirect you need to
> make sure that you're not going to send back anything other than the
> redirect.  If you do send something most clients will work properly, but
> some won't.
> 

Filters are like mini-servlets sort of, but they intercept a request for 
a resource and do something before passing the request along to the 
resource.  In my case, I wanted to call sendRedirect() from the filter, 
but it looks like that doesn't happen fast enough.  Using a return 
statement to terminate the doFilter() method call before it calls 
doFilterChain() seems to work though, as suggested by Tim Moore.

The nice thing about a Filter is you can have one Filter mapped to every 
resource in the site, I'm not sure how you could get that with a regular 
servlet...


Erik


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: INSECURE to rely on sendRedirect (??)

Posted by Erik Price <ep...@ptc.com>.

Craig R. McClanahan wrote:

> If you're sending a redirect from a servlet (or a filter) via Java code,
> you must do a "return" statement afterwards to avoid sending the rest of
> the content that would otherwise be sent:
> 
>   response.sendRedirect(...);
>   return;

Thanks for your confirmation on this.

> Same thing goes if you are (shudder) doing the redirect from within a JSP
> page:
> 
>   <%
>     response.sendRedirect(...);
>     return;
>   %>

I gather from your posts (this and others) that you're not a fan of 
putting decision logic in the JSPs!! :)


Erik


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: INSECURE to rely on sendRedirect (??)

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Fri, 24 Jan 2003, Mike Jackson wrote:

>
> I've had problems with something in a similar way, I have a login page in
> which if the login is successfull it will while send back a redirect to the
> client.  That redirect is supposed to go to the menu page for the webapp,
> but because the jsp is not only sending the header back, but some content
> (several blank lines) I have found that some versions on IE will become
> confused and ignore the redirect.  My solution was to move the login into a
> servlet and then to have the servlet send the redirect without sending any
> content (it's better practice to do that anyway).
>

If you're sending a redirect from a servlet (or a filter) via Java code,
you must do a "return" statement afterwards to avoid sending the rest of
the content that would otherwise be sent:

  response.sendRedirect(...);
  return;

Same thing goes if you are (shudder) doing the redirect from within a JSP
page:

  <%
    response.sendRedirect(...);
    return;
  %>

> So, in the end, I'm not clear on how filters work exactly (haven't needed to
> use them yet), but when you're using the header type redirect you need to
> make sure that you're not going to send back anything other than the
> redirect.  If you do send something most clients will work properly, but
> some won't.
>

> --mikej

Craig



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: INSECURE to rely on sendRedirect (??)

Posted by Mike Jackson <mj...@cdi-hq.com>.
I've had problems with something in a similar way, I have a login page in
which if the login is successfull it will while send back a redirect to the
client.  That redirect is supposed to go to the menu page for the webapp,
but because the jsp is not only sending the header back, but some content
(several blank lines) I have found that some versions on IE will become
confused and ignore the redirect.  My solution was to move the login into a
servlet and then to have the servlet send the redirect without sending any
content (it's better practice to do that anyway).

So, in the end, I'm not clear on how filters work exactly (haven't needed to
use them yet), but when you're using the header type redirect you need to
make sure that you're not going to send back anything other than the
redirect.  If you do send something most clients will work properly, but
some won't.

--mikej
-=-----
mike jackson
mjackson@cdi-hq.com

> -----Original Message-----
> From: Erik Price [mailto:eprice@ptc.com]
> Sent: Friday, January 24, 2003 9:52 AM
> To: Tomcat Users List
> Subject: INSECURE to rely on sendRedirect (??)
>
>
>
> A few weeks ago I posted a question on this list asking if using
> response.sendRedirect() is a secure means of preventing a user agent
> from accessing content.  (For instance, in a scenario where, to access
> the content, the session is consulted for a key of some sort.  If the
> key is found, continue, otherwise a sendRedirect() is used to send the
> user to an error page.)
>
> Since a redirect is performed using an HTTP header (rather than at the
> server, like RequestDispatcher.forward()), the user agent is not
> *obligated* to respect the redirect.  This means that relying on a
> redirect to protect secure data might be a mistake.  In other server
> side languages (Perl, PHP), you can call exit immediately after setting
> the header to ensure that the sensitive data is not sent from the server
> to the user agent in the event that the user agent does not respect the
> redirect.  However, as Paul Yunusov on this list pointed out to me, you
> cannot simply exit a servlet, it is not the same as a PHP or Perl
> script.  (The original message is appended to this one.)
>
> The servlet spec says that further output should not be sent from a
> servlet that has called response.sendRedirect(), which means that in
> theory the sensitive data is protected.  However, I have run into a case
> where sendRedirect() does *not* prevent a request from being made
> to a JSP:
>
> I am running Tomcat 4.0.6 and have a Filter named SecurityFilter mapped
> to a JSP named "main.jsp".  SecurityFilter consults the session for a
> key that is set when a user successfully passes through a login system.
>   If the key is present, then the Filter does nothing and the "main.jsp"
> page is served to the user.  However, if the key is not present, the
> Filter calls response.sendRedirect() to send the user to the login page.
>   In my case, "main.jsp" retrieves a bean from the session with the
> <jsp:useBean> tag.
>
> THE PROBLEM:  When a user who has not yet started a session and
> registered the bean that "main.jsp" is looking for attempts to request
> "main.jsp", SecurityFilter should redirect the user to the login page.
> However, what actually happens is that for some reason the redirect is
> not happening immediately when it is called, and the Filter calling
> doFilterChain(), which means "main.jsp", which means that the JSP throws
> an exception because it cannot find the bean in the session.
>
> Summary:
>
> 1) Calling sendRedirect() from a Filter does not happen before the
> Filter calls its doFilterChain() method
> 2) This means relying on sendRedirect() to protect sensitive data is
> probably not safe.
>
> There could be a flaw in my logic, or I could simply be stating the
> obvious and everyone knew this.  If either of those is the case, please
> point out my fallacy and I apologize for wasting everyone's time. :)
>
>
> Erik
>
> PS: to correct my situation, should I just not call doFilterChain() in
> my Filter if the login key is not found?  Or would that violate the
> Filter spec....?
>
>
>
> Paul Yunusov wrote:
> > On Friday 10 January 2003 03:42 pm, Erik Price wrote:
> >
> >>Paul Yunusov wrote:
> >>
> >>>sendRedirect() in HttpServletResponse will send an HTTP
> redirect response
> >>>to the client so the client's browser itself makes a new request to the
> >>>new URL (main.jsp in your case). It results in the new URL
> being shown in
> >>>the browser's address field.
> >>
> >>Paul, this is exactly what I was looking for!  Thank you.  My only fear
> >>is that if the client User Agent doesn't respect the HTTP Redirect (say
> >>it is a malicious Perl script or something), does the servlet know not
> >>to transmit any further data?  Or should I manually call System.exit()
> >>after the response.sendRedirect() call?
> >
> >
> >
> > Well, the API docs say "After using this method, the response should be
> > considered to be committed and should not be written to" so I guess the
> > developer rather than the servlet should know not to transmit
> any further
> > data from the servlet.
> >
> > Definitely no System.exit() in servlets as that would
> theoretically attempt to
> > shut down the Tomcat process itself but I don't know anything about any
> > practical repercussions. You could try that and let us know
> what happened.
> > :-)
> >
> >
> >
> >>>Note that the original request's parameters, which were sent to the
> >>>servlet, are lost but check the sendRedirect()'s documentation for more
> >>>details.
> >>
> >>That is okay, I will be storing data in the session in the LoginServlet
> >>so the original parameters can be dropped.  Thank you very much again.
> >
> >
> > Yes, holding the data in the session is what I thought you'd
> do, and I am glad
> > I could be of any help.
> >
> >
> >>
> >>Erik
> >
> >
> > Paul
> >
> > --
> > To unsubscribe, e-mail:
<ma...@jakarta.apache.org>
> For additional commands, e-mail:
<ma...@jakarta.apache.org>
>
>


--
To unsubscribe, e-mail:
<ma...@jakarta.apache.org>
For additional commands, e-mail:
<ma...@jakarta.apache.org>



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>