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…
The browser makes an AJAX request that submits the data with a dryrun=1 to indicate that settings should not be applied.
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).
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.
When the user clicks the Connect button, the browser POSTs to the server the following data:
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?
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:
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
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.