Industry Observations

A Tale of Responsible Disclosure

In the past few months I’ve taken on cycling as a new hobby, and one of the services I have been using to track routes and mileage is a popular webapp known as MapMyRide. They actually have several services that are split up per activity including MapMyFitness, MapMyHike, MapMyWalk, and MapMyRun. Several colleagues have also joined me in recreational cycling, so one day I decided to plan out a route for us to use repeatedly. After the route was created using MapMyRide, I decided to give it the quirky name Tour de <’hackers”>. It would get a laugh out of any XSS hunters because most of us in application security would recognize it as a benign HTML tag that also checks for single and double quote attribute breaks.

Image1

Take a close look at the “Share via Tweet/Facebook/Email” section

Image2

Oh my…

Whelp, that’s awesome, I’ve now inadvertently done the number one thing an ethical pentester should never do, and that’s play “outside of the sandbox.” You see, companies that don’t have an extremely active security team don’t really distinguish between a security professional that may be using the application legitimately, or an actual intruder that’s digging for exploits. Those of us that are paid to ethically hack into web applications and services are normally protected by various legal documents as per the contract of said penetration tests. XSS isn’t really hard to find – and truthfully I’m quite annoyed with all of its hype – but to a company it really doesn’t matter how cool or complex the exploit is so long as it’s damaging in some fashion to the business or brand. This particular one is persistent and easily wormable. If anyone remembers using MySpace (I admit that I did and accept the shame for it) they might be familiar with the MySpace Samy Worm that infected around a million profiles in less than 24 hours. Samy Kamkar’s XSS injection made you friend request him and added a little text to your profile page that said “but most of all, samy is my hero.” Silly, right? Well, what’s not silly is that his home was raided and he ended up entering a felony plea agreement that involved three years probation without computer use.

Let’s look at the facts. I don’t know if the makers of MapMyRide have an intrusion detection system (IDS) in place or if anything has flagged internally on this input. A quick Google search doesn’t reveal anything about them participating in Bug Bounties or Responsible Disclosure. I also did this on an account that is quite visibly linked to my personal Facebook account, so there’s a first and last name right there. All I can do now is approach them with what I’ve found, state my case and my intent, and hope that they seem me as a “do-good” individual that wants to ethically disclose the issue.

I hunted down a MapMyRide co-owner’s Twitter handle through LinkedIn, who then referred me to their VP of Engineering, Jesse Demmel. Now I can’t just email him saying that I was able to break the HTML document because that might not warrant enough attention. I’m going to have to send them an actual proof of concept and cause more injections to go through. Thankfully (open to interpretation) there wasn’t any input validation in place at all and we could call the cookies easily with <svg/onload=alert(document.cookies)>. Voilà.

Image3

Then things started getting a bit more interesting. I realized that the other domains shared this exact same template. This injection isn’t only persistent on mapmyride.com, but on the other four as well!

Image4

Image5

Image6

Image7

So, if I were to actually exploit this across all five domains from one entry point, how many people would I affect?

Here are some WolframAlpha statistics:

Image8

Based on those numbers, total page views across all sites are approximately 1,353,300 per day with 431,800 daily visitors. That’s not too shabby of a victim pool. With this injection I could make anyone that viewed any of these “routes” deactivate their account, change their profile information, change their profile pictures, steal their addresses, make things they’ve set as private now turn to public, have them each create support tickets to overload customer service, etc. etc., while also causing each victim to become a carrier of the injection which will cause an exponential increase in infection. Basically, anything within the context of the application is now accessible to me through JavaScript execution. I now carefully worded an email to Mr. Demmel explaining the severity and impact of the vulnerability and he responded in less than 24 hours:

“Hey Jonathan,

Sorry I didn’t get back to you sooner as I was traveling. Thanks for the details. We take this very seriously and are actively working on a fix, which we hope to push live shortly.

We have escaping turned on in Django and are using the latest version. This will require a patch and we’re working through that today (and the weekend if necessary).

I really appreciate you bringing this to our attention. We have gone through security audits in the past and have another scheduled soon.

Thanks“

The moral of this story: If you’re going to responsibly disclose I suggest the following things:

  1. Contact the highest person in the organization chain as possible initially. If you start by contacting someone like a customer support representative they may have no idea what you’re talking about. I’ve reported a bug once before and my first contact thought I was talking about spelling/grammar mistakes. This time I went straight to the co-owner.
  2. Don’t threaten with blog posts or say “I’ve reached out to Gawker, HuffingtonPost, or Threatpost and they’re ready to run this story, whatcha gonna do to fix it?” You’ll look like the enemy really quick and won’t be doing yourself any favors.
  3. Don’t ask for a reward. There’s a simple word for this: extortion.
  4. Simply make your intentions known. Know how to spot XSS, SQLi, or RCE by casually browsing an application that you use personally? You’re one-in-a-million (quite literally). Use your knowledge not only to report the problem, but also to tell them how they can fix it in case they are unaware. Intentions and thoughtfulness will go the longest for you in these regards.
  5. If you’re going to blog about it, like I’m doing here, wait until the issue is fixed and no longer exploitable (at least by the same attack vector). Asking for permission is wise as well, so that they can coordinate a release statement at the same time. Again, work with them, not against them.

Happy hacking.