Google Voice Vulnerability

I’m the type of person that likes to figure out how stuff is architected and built. Whether it’s a building or software, it doesn’t matter.

One day, I was interested to find out how the process of adding a forwarding number works and if it might be possible to mess with it. Luckily for me, I did find such a way.

The first thing I do is open up the Developer Tools in Chrome and open the Network display and watch the traffic going back and forth. Here’s what happens…

Verification Process

The browser makes an AJAX request that submits the data with a dryrun=1 to indicate that settings should not be applied.

HTTP Activity

The server then responds with a JSON object basically saying that things look ok. The browser then fires off another AJAX request without the dryrun=1 to tell the server to apply the settings.

The browser receives a JSON object with all the details for the phone just submitted. The important piece here is the phone id (data.id).

More HTTP Activity

The browser then displays the box that verification is required before the phone is active. The box displays a verification code that will be entered on the phone. The user then clicks Connect.

Verify your Phone prompt

When the user clicks the Connect button, the browser POSTs to the server the following data:

POSTing the verification code

Notice that the data sent consists of the phoneId (the same as data.id before), code (the verification code we are going to type into the phone), and forwardingNumber.

Wait one second! You mean to tell me that we are providing a phoneId AND a forwardingNumber? Shouldn’t the server (who just sent me the phone object) know what phone number is connected to the id I’m providing? What happens if I change the forwarding number to another phone number?

So, I wrote up a little Javascript (included jQuery because it just makes it a little easier and cleaner) to change the POST values. Low and behold IT WORKED! I was able to add any phone number, but have it call my own phone.

Basically, this vulnerability allows me to add any phone number as a forwarding number, regardless of whether I actually have access to the device. So… looks like this:

Modified timeline with attack

I then decided to email Google and let them know. So, I cleaned up my proof of concept code, wrote up an email, and fired away… not sure what to expect.

They got back to me pretty quickly and confirmed it was a problem and that it qualified for part of the bounty payout program. Woohoo!

As of last week, a fix was pushed up to production (which I have confirmed) that stops this vector.

Proof of Concept Code

Recap/Lesson

This is yet another reminder for developers that every input must be verified. In this case, the forwardingNumber doesn’t even need to be provided, but it is. If it is to be provided, it MUST be verified server-side.