How To Use Google Maps API Keys For Free

The use of a Google API Key can be restricted to a configurable set of host or domain names. But does this protect (ab)use of the key by others? Not really.

Stolen key
unsplash-logoErik Mclean

Two remarks upfront: First, I do not want to encourage anybody using someone else's API key. Of course not. But if you are a paying Google customer, you should be aware that Google actually cannot guarantee that the keys can only be used in a way intended by you.

Second, the problem is not specific to Google Maps. It is not even specific to Google services at all, since other service providers use the same logic. The Google Maps API is just a good example because it is used on so many websites.

How Is the Key Used?

The key is transmitted as a URI parameter, when the JavaScript is requested from the server, for example:

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY&libraries=places,geometry&callback=initAutocomplete"
        async defer></script>

The key is therefore not a secret. It is necessarily visible in the source code of the web page consuming the API.

And - very handy - it is trivial to collect these keys in large numbers with any web crawler. You can even get a hint which parts of the API ("places", "geometry", "drawing", "visualization") are usable with a specific key.

How Does the Protection Work?

You can configure a list of host and domain names that are allowed to "use" a specific API key. Using means that API requests are made from an origin (a web page) hosted on an allowed host (name!).

But how does the JavaScript code "know" the origin of the page? It gets it from the browser! And that means that the information is unreliable. For example users may patch their browser's source code to supply wrong information.

The Exploit

But there is no need to patch your browser's source code and recompile it! There is a far easier way.

Most keys will be usable from the origin "localhost" and/or "127.0.0.1" to allow local development. It is definitely worth a try at least. So if you run your own web application on "localhost" (and you do, don't you?), just about any API key you can find will do for you. That is the free tier for development that Google does not offer.

But even if a key owner wants to be clever and creates a production key that cannot be used with the loopback interface, there is no need to worry for the abuser. You just edit your /etc/hosts:

127.0.0.1 www.my-ex-employer.com

And you are set again! Your local application is now hosted on www.my-ex-employer.com.

Why Not IP-Based Protection?

Think about it yourself for a second ...

JavaScript cannot find out the IP address of the host serving the code. And from Google's side, this also does not help. If you abuse the key for www.my-ex-employer.com locally, the API calls from your local application are indistinguishable from legitimate calls coming from an application hosted on the real IP of www.my-ex-employer.com.

Google can, of course, implement rate-limiting, and I am pretty sure they do. But that is just a litte band-aid and not a remedy.

But What Is the Benefit?

So you can develop a web app for your new project www.alone-again.com using the Google Maps API key that you have taken from www.my-ex-employer.com. But the fun is over, when you deploy the site on the real IP of www.alone-again.com. You personally can patch your browser, or you can edit your /etc/hosts but the visitors of your site will not, and the API calls will fail.

Yes, true, but not completely. You can simply proxy the requests through your own server and you are done. Writing such a little proxy with Express should be a piece of cake for an average web developer.

The Legal Situation (in Germany)

Using other people's keys is probably against Google's terms and conditions for their maps service. But does it matter? No! An attacker can use the API without accepting Google's terms and conditions. A contract not made cannot be breached.

But can the victim hold the attacker liable for the damage? Every API call has to be paid for and so there can be a substantial damage.

That would be the case if the attacker acts illegally, in other words, if a contract or law was broken.

The attacker neither has a contract with Google nor with the victim. But was a law broken? In Germany, there is a law against so-called computer fraud that sanctionizes use of invalid or incomplete data or unauthorized use of data.

I cannot conclusively say whether this law or any other law would be broken, and to be honest I also do not want to say that, because I do not want to encourage anybody to damage anybody else's assets in such a way. But my impression is that the chain of arguments needed to classify such a case as computer-fraud would be pretty lame.

On the other hand, the victim can without doubt hold Google liable for the damage by simply not paying for the illegitimate API calls. But how find that out, when you cannot even see the IPs from which the calls have been made? And even if you knew the IPs, how would you distinguish abuse of your API key from users hitting F5 just for fun or out of spite?

Google's Position

Weeks ago, I have asked Google for a comment from inside the Google Cloud Platform Console. I am still waiting for any reaction from their side.

But just to reassure the anxious: We are talking about services that are charged with micro-cent-prices per request and it is more than likely that Google has countermeasures against an exploit at large scale. But it leaves a bad taste in the mouth nevertheless that Google uses an utterly non-transparent billing model that is vulnerable to boot.

Conclusion

The standard way how JavaScript API keys are protected is brittle at best. Attackers that run small sites compared to the site that the key was "stolen" from have little to fear.

Leave a comment

Abusing JSON.stringify()

Hidden Quirks of JavaScript `for...in` Loops

Creating E-Invoices with Free and Open Source Software

Dynamic Angular Configuration

Compiling ImageMagick for Perl

Standalone Angular Tour Of Heroes

This website uses cookies and similar technologies to provide certain features, enhance the user experience and deliver content that is relevant to your interests. Depending on their purpose, analysis and marketing cookies may be used in addition to technically necessary cookies. By clicking on "Agree and continue", you declare your consent to the use of the aforementioned cookies. Here you can make detailed settings or revoke your consent (in part if necessary) with effect for the future. For further information, please refer to our Privacy Policy.