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.