Do I need to hide API key when using google maps js API? If so, how?

30,540

Solution 1

You can create multiple API keys with different restrictions to use them safely. For embedding a map, the Google Maps documentation has instructions for creating a correctly restricted API key so that it cannot be abused for other purposes at Get an API Key - Restricting API keys. It's OK to include a restricted API key in your source code, because you cannot embed a map properly without doing that anyway.

If you need server-side API access, you can create a second API key with less restrictions. That one should be kept secret.

Solution 2

While the above answers are helpful, none of them addresses the following vulnerability:

Once a user has access to your API key, even if they are restricted to using it only from your domain, they can still use it as much as they want. In the crudest sense, this could mean a million page refreshes (and map loads) in a very small amount of time, consequently putting you over your usage quota.

I haven't come across any solutions that address this issue. Unless I'm missing something...?

Relevant usage limits for google maps javascript api here.

Solution 3

The link that you posted that says you shouldn't embed API keys in code is related to Google's Cloud Platform. You are fine to leave your API key for Google Maps in your code.

Solution 4

To hide an API key for any service:

  1. Design a web server that will accept requests for the third party service and proxy requests to them.
  2. Design your interface to make requests to the web server that you designed in step 1.
  3. Store the key on the web server you built in step 1, and apply authentication, authorization and rate limiting to the 3rd party proxied requests.

The 3rd party libraries that you use might force you to use certain hosts or might force you to include an API key. For the first problem, you'll have to either edit their library code, or provide the 3rd party client library with a different http request library, like redefining the fetch() function in javascript for example. For the second problem, just add a garbage key and your proxy server can ignore it and re-write it with the real key.

Benefits:
  • Hide your keys.
  • Track who, what, and when for requests and responses. You could do this other ways though.
  • Could add a layer of caching to the service to speed up requests that other users have made before, provided that their terms of service allows it.
Caveats:
  1. Because users will be making requests pretending to be your server, you are accepting a security risk. If the user intentionally makes maliciously formatted requests, they are doing so while appearing to be your server. You can however log all requests if you want to audit them later.
  2. It takes more than a couple seconds to build and configure the proxy server with all the security you require.
  3. You now need to handle all of these web requests which may be a lot of traffic.
  4. You may want to intercept the responses the server returns in case it returns the key in the response body during in an error or otherwise.
  5. You are adding another link in the chain and it will make the service slightly less reliable.
Mentions

I wanted to mention that this is essentially what "@OLTO and SUGI-cube Project" was trying to demonstrate in their answer and what #Brandon Miller was suggesting as a solution in a comment.

Solution 5

No need to hide API key, you just have to make it useless, You can simply use key restrictions on the google API console.

from google API console choose:-

  1. credentials
  2. choose your API key or create a new one
  3. Application restrictions
  4. HTTP referrers (websites)

and then add your Website restrictions

Share:
30,540
fstang
Author by

fstang

Updated on July 09, 2022

Comments

  • fstang
    fstang almost 2 years

    According to https://developers.google.com/maps/documentation/javascript/tutorial#HTML5 , it seems I can add the following tag to my html and start using maps js API.

    <script async defer
          src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
    </script>
    

    But this will reveal my API key.

    After searching on google and browsing answers on stackoverflow, I feel that maybe there is no need to hide this API key. I just need to set the referer when I create the API key on google, as explained in https://stackoverflow.com/a/2256312/1316649

    So, even others know my API key, they cannot use it from another domain. Am I right?

    But google says you shouldn't embed API key in code: https://support.google.com/cloud/answer/6310037

    So, do I need to hide API key when using google maps js API? If so, how?

    Update: By 'API key', I meant browser API key.

  • fstang
    fstang almost 8 years
    Thanks for the answer! I'm asking about the browser key. I will update the question.
  • Gustavo
    Gustavo over 6 years
    There is a API for geolocation by javascript. It suppose to be hidden as it is staten in the tutorial, so I did a function only to get it on fly silently - but it is always the same key! The information about those keys are unclear in Google Dev, thanks for clarifying!
  • Håkan KA
    Håkan KA over 6 years
    I don't think anything can be done about that without some kind of own back-end implementation to restrict hammering.
  • Kevin Workman
    Kevin Workman over 5 years
    I'm upvoting because I was searching for posts that talked about the problem of malicious users exhausting the quota, but I don't think this really attempts to answer the question.
  • Martin Zvarík
    Martin Zvarík over 5 years
    Restricting referer does absolutely nothing, anyone can spoof it. And restricting over IP can't be done for public page like contact page, because you can't list all visitors IPs.
  • Blue Clouds
    Blue Clouds almost 5 years
    this is the problem I need to address
  • isopach
    isopach over 4 years
    You can restrict the API keys. Your quota would not be affected.
  • bers
    bers almost 4 years
    Not sure this answer is extremely helpful, as Google Cloud Platform is where you get the Maps API key in the first place. See developers.google.com/maps/documentation/javascript/get-api-‌​key
  • sirlark
    sirlark over 3 years
    Google no longer distinguishes between key types, and all security options are available on all keys (at writing time of Nov 2020). See cloud.google.com/docs/authentication/api-keys
  • Matti Virkkunen
    Matti Virkkunen over 3 years
    @sirlark Thanks. I've updated the answer to reflect how things work now.
  • Matthew Dresser
    Matthew Dresser over 3 years
    This does not help to hide the API key very much. An ajax request is still made which contains the key - users are still free to view that request and look at the key. Also, if they use inspect element in their browser, they are likely to find the key that way too.
  • OLTO and SUGI-cube Project
    OLTO and SUGI-cube Project over 3 years
    Thank you for your information. I have found APIKEY in ajax result js-text just now. This can hide APIKEY only from published source like on GitHub. Once execute this on my server, everyone could know my APIKEY. What shall I do then? I want to hide MYKEY. Can anyone help me?
  • Daniel Jeney
    Daniel Jeney over 2 years
    You can restrict quotas per ip per 100seconds or per day - youtube.com/watch?v=A8bsgHUYsq8
  • Brandon Miller
    Brandon Miller over 2 years
    Assuming you are on an infra that has access to a gateway/reverse proxy/ingress etc, you could always use a rate limiter. Could even create your own with a bit of creativity and possibly a serverless function.
  • Kay. T
    Kay. T over 2 years
    This might help > Maps JavaScript API Usage and Billing \| Google Developers You can limit number of requests in 3 ways. 1. Map loads per day 2. Map loads per minute 3. Map loads per minute per user