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]

Reply via email to