Friday, November 11, 2011

Issues with jsessionid in url

When application server will append jsessionid to url?
If the request is first from client and there are no cookies (related to that commerce site) at client side,
   then application server will create new session and have that sessionid appended to url (as url agrument parameter seperated by ";" its not query parameter "?")
 and will also set jsessionid cookie at the client side.

Why application server is appending to url?  
To support browsers which do not allow cookies.
As mentioned in  http://randomcoder.org/articles/jsessionid-considered-harmful
"Cookieless sessions are achieved in Java by appending a string of the format ;jsessionid=SESSION_IDENTIFIER to the end of a URL. To do this, all links emitted by your website need to be passed through either HttpServletResponse.encodeURL(), either directly or through mechanisms such as the JSTL <c:out /> tag. Failure to do this for even a single link can result in your users losing their session forever." 

 For example: in url
 http://localhost:8080/store/store/product/view_product_details.jsp;jsessionid=EF8300224952E06E951475223380F9B0?_DARGS=/store/store/product/includes/vpd_product_selection_display_fg.jsp

And in the generated html page - 
<form action="/store/store/product/view_product_details.jsp;jsessionid=EF08475F9F98B45556DCA1946F35C013_DARGS=/store/store/product/includes/vpd_product_selection_display_fg.jsp" method="post" id="add-to-cart">

Issues having jsessionid in url
But having "jsessionid" in the url leads to below problems
1) If we are caching the common pages at AKAMAI level.
     For example:
User 1 requested page product_details.jsp and Since it is the first request, appserver includes jsessionid in the urls in the generated page. 
Akamai cached the page (product_details.jsp) which got generated for user 1. 
When user 2 requested same page, Akamai serves that cached page, the request wont even go to web server or app server. 
Now if the user 2 tries to add an item, the form action url contains a session id of user 1 and when it comes to webserver/load balancer
which redirects the request based on sessionid to appserver, the appserver will add the item to user 2 session.

2) Google bot problems as mentioned in http://randomcoder.org/articles/jsessionid-considered-harmful
    "To prevent abuse, search engines such as Google associate web content with a single URL, and penalize sites which have identical content reachable from multiple, unique URLs. Because a URL-encoded session is unique per visit, multiple visits by the same search engine bot will return identical content with different URLs. This is not an uncommon problem; a test search for ;jsessionid in URLs returned around 79 million search results."

   "Because the session identifier is included in the URL, an attacker could potentially impersonate a victim by getting the victim to follow a session-encoded URL to your site. If the victim logs in, the attacker is logged in as well - exposing any personal or confidential information the victim has access to. This can be mitigated somewhat by using short timeouts on sessions, but that tends to annoy legitimate users." 

How to fix above issues?
Below are three ways to fix this issue.
1) Fix using filter is mentioned in http://randomcoder.org/articles/jsessionid-considered-harmful

Assuming you have mod_rewrite enabled in your Apache instance, use this configuration in your apache config:



# This should strip out jsessionids from google
RewriteCond %{HTTP_USER_AGENT} (googlebot) [NC]
ReWriteRule ^(.*);jsessionid=[A-Za-z0-9]+(.*)$ $1$2 [L,R=301]
This rule says for request where the user agent contains “googlebot” (with case insensitive matching), rewrite the URL without the jsessionid. It seems to work nicely.
By using above way url rewriting is done at web server level.

3)Other way is to use http://www.tuckey.org/urlrewrite/
"Based on the popular and very useful mod_rewrite for apache, UrlRewriteFilter is a Java Web Filter for any J2EE compliant web application server (such as ResinOrion or Tomcat), which allows you to rewrite URLs before they get to your code. It is a very powerful tool just like Apache's mod_rewrite."

Example - 
in /WEB-INF/web.xml
      <filter>
            <filter-name>UrlRewriteFilter</filter-name>
            <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
            <init-param>
                  <param-name>logLevel</param-name>
                  <param-value>INFO</param-value>
            </init-param>

            <init-param>
                  <param-name>confPath</param-name>
                  <param-value>/WEB-INF/urlrewrite.xml</param-value>
            </init-param>
      </filter>

      <filter-mapping>
            <filter-name>UrlRewriteFilter</filter-name>
            <url-pattern>/*</url-pattern>
      </filter-mapping>

in urlrewrite.xml
     <rule>
          <from>^(.*);jsessionid=[A-Za-z0-9\-\+\*\._]+(.*)$</from>
          <to type="redirect">$1$2</to>
     </rule>
Please note that this filter mapping should be before PageFilter, so that before handling request to PageFilter the jsessionid should be stripped from url.

2 comments: