Magento Session Fixation Workaround
20 Mar 2010, by Lloyd Hazlett
5 Comments · Posted in Magento

    Earlier versions of Magento were susceptible to a form of session fixation vulnerability, which can have quite serious consequences even without anyone trying to exploit it maliciously. Visitors may unwittingly follow a link to a Magento site, and be logged in as another user without performing any actions. This results in multiple visitors sharing a session and causes confusion as they add and remove things from the same cart, and potentially even allows them to view another customer's details and place orders under their account. Luckily the issue has a simple fix in version 1.4 and later, but in this post we'll also detail a precaution that can be taken to guard against this in earlier versions.

    The problem stems from a feature whereby the session ID is passed as a GET parameter when the URL by which the current Magento store is being accessed doesn't match that store's base URL. This feature was designed to support a user freely switching between stores within the one site. However, it is quite common for a site to be accessible by two or more URLs (e.g. domain both with and without www), and links that are generated when accessing the site via any URL that is not the base URL will have a SID parameter included in the query string. If a URL of this form is then distributed to many people through an email campaign, ad link, data feed, or by other means, then they may share the session identified by the SID in the URL for as long as it is valid. The person distributing the URL might have quite innocently stumbled into the URL that includes the SID, for example by directly entering the domain name without the www but where the base URL includes it.

    As a workaround, assuming we have Apache rewrites enabled, then we can use a rewrite to remove the offending SID parameter from the query string altogether. The following rewrite would be used before any rewrites of the request to Magento:

    # Covers the case where there are more parameters that follow SID=XXXX
    # We rewrite the query (foo=bar&)SID=XXXX&(baz=naz) to just foo=bar&baz=naz.
    # The ampersand following the preceding parameters, if they are present, is retained.
    RewriteCond %{QUERY_STRING} ^(.+&)?SID=[w]*&(.+)?$ [NC]
    RewriteRule ^(.*)$ /$1?%1%2 [R=301,L,NE]
    # Covers the case where there are no more parameters follow SID=XXXX
    # We rewrite the query (foo=bar)&SID=XXXX to just foo=bar.
    # The ampersand following the preceding parameters, if they are present, is discarded.
    RewriteCond %{QUERY_STRING} ^((.+)&)?SID=[w]*$ [NC]
    RewriteRule ^(.*)$ /$1?%2 [R=301,L,NE]

    The rewrites handle two cases covering whether there are additional parameters following SID or not. One advantage of this approach is that it requires no modification of the application itself and provides an extra layer of security for your website. It could also conceivably be used for other applications aside from Magento to prevent similar problems.

    To turn the option off in Magento 1.4 and later, set "Use SID on Frontend" to "No" under System → Configuration → Web → Session Validation Settings:

    Note that the rewrite detailed above shouldn't interfere with anything else, and could always be left in place following a 1.4 upgrade to guard against the setting ever accidentally being turned back on.


    Thank you for this post, you are a life saver Lloyd, I can't believe how difficult it was to locate this fix.

    1. My site uses magento v1.3.2.3. How can I find out whether I have apache rewrites enabled, is it a host thing?

    2. Where do I copy and paste your code into.

    Thanks again!
    Comment by Anonymous - 21 Jun 2010 1:15:00 PM
    If you are unsure of how to setup the rewrites, this should probably be handled by your hosting provider who would know where to make the appropriate changes for your site. Exactly where these directives need to be placed will depend on your specific hosting setup, but most commonly they would be added to a .htaccess file. Hope this helps.
    Comment by Lloyd Hazlett - 22 Jun 2010 2:31:19 PM
    Very usefull explanation. And coding examples.

    This also applies to the Zend TwoLevel caching implementations ?
    Comment by Nils Eriksen - 2 Aug 2010 5:57:47 PM
    thanks for this articles really helpful for us..
    Comment by rhizann2 - 9 Sep 2010 2:19:00 PM
    Thanks for this article, it helped us!

    Your RewriteRules block Flash-based image uploads (the 301 redirect breaks the uploader).

    Our version of your RewriteRules with a fix for that:

    <code lang="apache">
    RewriteCond %{QUERY_STRING} ^(.+&)?SID=[\w]*&(.+)?$ [NC]
    RewriteCond %{QUERY_STRING} ^/index.php/admin/catalog_product_gallery/upload/key/$
    RewriteRule ^(.*)$ /$1?%1%2 [R=301,L,NE]

    RewriteCond %{QUERY_STRING} ^((.+)&)?SID=[\w]*$ [NC]
    RewriteCond %{QUERY_STRING} ^/index.php/admin/catalog_product_gallery/upload/key/$
    RewriteRule ^(.*)$ /$1?%2 [R=301,L,NE]

    Hope this helps!

    Comment by Sebastian - 25 Sep 2010 10:49:00 PM
    Comments are closed for this post