How I found a $5,000 Google Maps XSS (by fiddling with Protobuf)

The Google Maps URL parameter format

Opening the hood

The requests loading Google Maps’s source, and some minified code
Some of the code of the function that does the mysterious kind of URL encoding — apparently.
  • An exclamation point: the separator.
  • A number: it looks like an integer key, in a key/value pair.
  • A single letter: it’s a type that determines what follows. “s” is a string, “i” is an integer, but there’s more…
  • Either a number, or a string: the value in the key/value pair.
A screenshot from Chrome’s web console, showing requests to various AJAX endpoints.
Samples of what Protobuf message definitions looks like (.proto format).
In our example, the “Person” Protobuf message is turned into a “Person” Java class
The programmer invokes the “Person” class and sets data
Data is serialized in a binary form
That would have barely identical meaning, in the format used to encode URL information.
// This function, found in Google Maps' code, says which type character should map to what default field value:dba = function(a) {
switch (a) {
case "d":
case "f":
case "i":
case "j":
case "u":
case "v":
case "x":
case "y":
case "g":
case "h":
case "n":
case "o":
case "e":
return 0; // Those are integers (and enum)...
case "s":
case "z":
case "B":
return ""; // Those are string/bytes...
case "b":
return !1; // This one is boolean...
return null // And there's also "m" for messages, referenced in further serialization code
We don’t want to make sense of this.

The first magical script

Some Websocket communication between Chrome and the Chrome developer tools (captured using Chrome developer tools themselves)
Code snip: some commands sent at Websocket creation, and the begin of event loop
_.Eqa.prototype.H = function(a, b) {
var c = Array(Fqa(a, b));
Gqa(a, b, c, 0);
return c.join("")
Sample data for the “a”, “b” and “c” local variables, respectively.
Some of the reconstructed .proto data
Some of the network endpoints, with captured data samples for each

The second nifty program

The Protobuf editor, our second creation, a slick way to edit and replay network data we captured at the previous step.

The 0-day

The proprietary “DRAT” format is used to transport maps in a vector format to the Android client.
Placing a arbitrarily named marker on the map, by editing request information. On this screenshot, this is done while requesting map tiles in a raster format (PNG).
Our original XSS payload looked like this. 🎉
The same payload, once the HTML string was base64-encoded.
The same payload, once we converted nested messages to wire format, then cast to base64 string — now that’s unintelligible.
With Google Maps, find nearby hot hackers from your area
A payload leveraging an existing place on the map.

Vendor response

The project

  • extractors/ that’s the main extraction .proto script, that launches Chrome, connects to its depths and does the stunning work. You can use it individually, just pass an URL as an argument.
  • views/ that’s the little GUI editing and replaying requests. It’s now integrated to the larger app, and that you can play with launching the GUI ( and clicking “Step 3…”. It will look for .protos stored in a folder of you home directory, as explained in the interface.
  • In addition, the code required to encode back and forth URL parameters in the “!”-separated format is bundled as a module in utils/ It is included by the previous.




Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Setup Coral/Talk Development Environment

Unlimited Addons for WPBakery Page Builder (Visual Composer) 1.0.42

Basic OOP for shavetail Louies — PART II [Abstraction]


AWS AppSync and the API Key

DevOps -part 4: CICD with Jenkins, docker; deploy to k8s cluster; AWS

MGTLIC #11 — Spend no time on what-ifs!

Handling Multiple Resultsets

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Marin Moulinier

Marin Moulinier

More from Medium


A BadUSB that isn’t so bad: Making a keystroke injector in Arduino that automates GatherTown…

DVWA — Task 1: Brute force using Hydra & Developer tools with Bonus task unlocked!

Internet Protocol (IP) for Nmap