Disabling Session Re-Writing in BlazeDS and LCDS

Session re-writing is the practice of adding the session identifier to the HTTP request URL instead of passing the session identifier as a session cookie. Session re-writing is usually used when cookies have been disabled on the client. It is an easy way to let clients that do not allow or support cookies maintain session state with the server but it poses some security risks. The session identifier is passed in the URL which means that it is not encrypted even if the request is made over SSL/HTTPS. Because of the security risks associated with session re-writing, the Open Web Application Security Project (OWASP) recommends that session re-writing only be used for low-value sites. In this article, I will show you how to disable session re-writing in BlazeDS and LCDS to help secure your application.

In BlazeDS and LCDS, the session identifier is typically either the JSessionId (for servlet based endpoints in BlazeDS or LCDS) or AMFSessionId (for NIO HTTP based endpoints in LCDS).

Note that the RTMP protocol doesn’t use HTTP, so the issue of session re-writing doesn’t apply to RTMP endpoints.

When the BlazeDS or LCDS server receives a request with no session identifier (either a session cookie or session id URL parameter) a couple things happen. A new session is created. A Set-Cookie header with the session id is added to the response. Also, an AppendToGatewayURL header with the session id is added to the AMF or AMFX response message.

The BlazeDS/LCDS client code looks for the AppendToGatewayURL header and will grab the AMFSessionId or JSessionId from the header. The client code will then add the session id as a URL parameter to every request made to the server. Here is what the request URL with the session id in URL parameter looks like.

http://localhost:2082/nioamfpoll;AMFSessionId=7467AE52-322F-407A-9254-E484586219CB

If cookies are supported by the browser, the browser will also send a session cookie with the session id with every request. If both a session cookie and session id URL parameter are found, the application server will typically use the session cookie and ignore the URL parameter.

The way that session re-writing is currently implemented in BlazeDS and LCDS is not ideal because the session id url parameter is often sent unnecessarily when the browser does in fact support cookies. This can be mitigated by making sure that an HTTP session already exists before a request is made to the BlazeDS/LCDS server. In that case, the server would not add the AppendToGatewayURL header to the AMF/AMFX response message and no session id URL parameter would be sent by the client.

Note that one way to do this would be to make the main page for the application be a jsp page that would create the HTTP session then return the BlazeDS/LCDS application SWF to the client.

This will make it so the client won’t send the session id in a URL parameter if cookies are enabled but what OWASP recommends is that this functionality be disabled altogether. Usually, app servers provide a switch do disable session re-writing. In BlazeDS/LCDS, there is no switch to disable this feature but luckily it is fairly easy to disable session re-writing on your own. This can be done by writing a custom channel.

The process for disabling session re-writing is slightly different for AMF and AMFX  channels.

Note that the channels that use the AMFX message format in BlazeDS and LCDS are named HTTP, for example HTTPChannel and StreamingHTTPChannel. To avoid confusing the HTTP in the channel name with the HTTP protocol, I refer to these channels as AMFX channels.

To disable session re-writing for one of the AMF channels, you just need to extend the channel and override the AppendToGatewayUrl function. Here is an example of a custom channel that extends AMFChannel to disable session re-writing.

package test.messaging.channels
{
    import mx.messaging.channels.AMFChannel;

    public class CustomAMFChannel extends AMFChannel
    {
        /**
         *  Constructor.
         *
         *  @param id The id of this Channel.
         *  @param uri The uri for this Channel.
         */
        public function CustomAMFChannel(id:String = null, uri:String = null)
        {
             super(id, uri);
        }
        /**
         *  Override AppendToGatewayUrl function to prevent session id from getting
         *  getting appended to the request URL.
         */
        override public function AppendToGatewayUrl(value:String):void
        {
            //no-op
        }
    }
}

To disable session re-writing for one of the AMFX channels, you just need to extend the channel and override the appendToURL setter. Since the setter is marked mx_internal you also need to make sure your custom class imports and uses the mx_internal namespace. Here is an example of a custom channel that extends HTTPChannel to disable session re-writing.

 
package test.messaging.channels
{
    import mx.messaging.channels.HTTPChannel;
    import mx.core.mx_internal;

    use namespace mx_internal;

    public class CustomHTTPChannel extends HTTPChannel
    {
        /**
         *  Constructor.
         *
         *  @param id The id of this Channel.
         *  @param uri The uri for this Channel.   
         */
        public function CustomHTTPChannel(id:String = null, uri:String = null)
        {
            super(id, uri);
        }
        /**
         *  Override appendToURL setter to prevent session id from getting appended 
         *  to the request URL. 
         */
        override mx_internal function set appendToURL(value:String):void
        {
            //no-op
        }
        
    }
}

To use the custom channel in your application all you need to do is create a ChannelSet that contains the custom channel and assign the ChannelSet to your BlazeDS/LCDS component (Producer, Consumer, DataService, etc.). Here is a code snippet that shows how to do this for Producer and Consumer components.

var cs:ChannelSet = new ChannelSet(); 
var ch:CustomHTTPChannel = new CustomHTTPChannel(null, "/qa-manual/messagebroker/httppolling");
cs.addChannel(ch); 
producer.channelSet = cs; 
consumer.channelSet = cs;   

Keep in mind that for any channel you create manually (rather than retrieving it from the ServerConfig), you need to set the endpoint URL yourself as well as any channel specific properties such as the polling interval.

I hope this article will help you make your BlazeDS/LCDS applications more secure. For more security best practices around session management, I recommend reading this OWASP session management guide.

About aglosband

I am a Quality Engineer at Adobe Systems working on the BlazeDS and LiveCycle Data Services products. I know a little bit about some things and more than a little about other things having to do with Adobe technologies and products such as BlazeDS, LCDS, Flex, and the Flash player. I have also spent a lot of time maintaining build and test automation systems, developing test frameworks and performing load and scalability testing. I'm hoping to share some of my knowledges and experiences in these areas with anyone who might also be interested in such *boring* stuff.
This entry was posted in BlazeDS, LCDS, Security. Bookmark the permalink.

4 Responses to Disabling Session Re-Writing in BlazeDS and LCDS

  1. Mike Slinn says:

    Alex,

    Thank you for your post; it is most interesting – and not boring (to me!)

    The Tomcat docs (http://tomcat.apache.org/tomcat-6.0-doc/config/context.html) seem to say that setting the disableURLRewriting attribute of the Context element false perform the same purpose as CustomHTTPChannel and CustomAMPChannel. Any comment?

    Also, the useHttpOnly attribute seems to provide extra security. Are you aware of any problems when using it?

    Mike

    • aglosband says:

      Thanks for the comments Mike. I’m aware that most app servers including Tomcat have the ability to disable URL rewriting at the app server level.

      The issue here is that BlazeDS and LCDS do their own custom URL rewriting. There is currently no switch to turn this off so even if you disabled URL rewriting at the app server level, BlazeDS/LCDS could still add the session id as a header to the AMF or AMFX message and the client would then pull this out send the session id on the URL with every request.

      So, even if you disable URL rewriting at the app server level I’d still recommend writing a custom channel to disable URL rewriting in BlazeDS/LCDS for high value sites.

      As for the HttpOnly attribute, I think it’s a good idea to use it even though not all browsers support it. I don’t see any issues using it with BlazeDS/LCDS.

  2. Mike Slinn says:

    Alex,

    Thanks for the information. I have added it to our Security White Paper for the Adobe Flash Platform.

    Mike

  3. Pingback: The ADEP Post | Disabling Session Re-Writing in BlazeDS and LCDS

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>