Tomas Hulek wrote:
Unfortunately, filters are skipped (ie. not called at all) when form-based
login page is processed as a result of client requesting a secure area.
We tried that too...
By the way, the original URL that the client requested is hidden in the
session in a way which prevents the web app from copying it to a new
session object.
Sorry I was thinking of the general usage case (I dont use Servlet spec
security contraints myself, the mechanisms I use are implemented in
application code). Its straightforward to fix the <security-constaints>
implementation to provide better security since it has access to
internal container code, but...
That still leaves a pure web-app developer out in the cold. Because
there is no mechanism for him to ask the HttpSession object if it has
been exposed to a non-secure channel. Only Tomcat can manage this extra
flag situation effectively because it is container code that is in
charge of session management and emitting the Set-Cookie line, so when
it does that it sets a flag if the connection is not considered a secure
channel.
This is the only missing building block a web-app developer needs to
know to be able to reliably fix the problem from there.
And like I said the client end of the problem is sorted with the
"Secure;" attribute. So the client can be trusted not to leak
information at the wrong time. The problem is that the lack of
mechanism at the server end to do the same.
The cleanest way to implement a solution is to have a
sessionIdHasBeenExposedViaUnsecureChannelFlag and also have a built in
HttpSession.makeSessionSecure();
public HttpSession makeSessionSecure(HttpServletRequest request) {
HttpSession newSession = null;
if(request.getScheme("HTTPS")) { // this might be too crude for
production use in detecting if the request is via a secure channel
// there is no point making the session secure if the request we are
currently on is not secure itself
if(thisSession.hasBeenExposedViaUnsecureChannelFlag()) {
newSession = HttpSession.createNewSession();
newSession.setSecure(true); // turns on the "Secure;" flag
// Ideally we should have a create and setSecure() as one atomic
action ensuring the session never existed for any moment without the
Secure flag set.
// Migrate data
for(Object o : thisSession.getAttributes()) {
newSession.setAttribute(o);
}
// Possibly do internal session management stuff (as necessary)
thisSession.invalidate();
// Possibly do stuff to force new Set-Cookie line in next response
(but I think that happens by default anyway, even through it does not
have to as the client remembers it)
}
}
return newSession;
}
Then the caller just needs to "security prune" the attributes that were
migrated after calling.
You could probably dump the 'request' argument, I was just making the
obvious point that there is no use making a session secure if we're not
already inside a secure channel. But that could be considered
misuse/application programming error.
The actual enforcement of secure channel can then be done easily inside
a regular web-app filter. With a check along the lines of
if(session.hasBeenExposedViaUnsecureChannelFlag()) {
session.invalidate()
}
I agree with the original poster, it is not practically possible to use
HTTPS for everything. The HTTP protocol has a clear mechanism to deal
with this security concern. The culprit here is the lack of
understanding on this issue by the Servlet specification and therefore
Tomcat.
In response to the guy suggesting different path's well the HTTP Cookie
specification allows for this also with the
Path="/ServletContext/secure"; attribute. But going down this avenue
you are placing unnecessary restrictions on a web-application, where as
the approach above does not.
Darryl
---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]