Allowed referrers in google maps API (cordova) - javascript

I created an API key for gmapsv3 but it's asking me for allowing some HTTP referrers.
What is the referrer for a cordova app, since there is no URL?
I left * for the moment but how to secure my key?
I'm under meteor and tries meteor.local, but it doesn't seem to work.
Thanks

You could potentially change the native code to add a referer, and lock your maps key down to that... there is an example of such here.
Alternatively if you want a platform independent solution you could add implement a proxy on your server, keep your Google Maps key there on the server and have it make requests to Google Maps on your behalf. This would introduce another layer of network calls, then you'd also want to secure your proxy so that you can be pretty sure that the requests are coming from your app - maybe by setting a custom HTTP header that your server can look for.

Related

Front-End API Token Exposure

My question is simple and general: when making calls to RESTFUL APIs, whether they be mine or external ones, is it common practice/ok to have the token exposed on the front end? For instance, in the documentation for the Google Maps api, they suggest the following code:
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"
async defer></script>
the fact that your API key is exposed on the front end for all to see is ok then? I guess google has has the option to restrict access, so that can solve that, but what about other services that don't give that option?
Is it better to keep my API calls on the backend to protect my tokens? Having them on the backend, I would think, would not be preferred, because they I cannot get the data asynchronously
In short , yes it's possible to use someone else API keys in your site if you can spoof http referer header on client system .In fact you can even saturate his quota completely if you have either of these
Full control over your clients browser (to manipulate HTTP headers it might send to google servers)
You own huge collection of unique IP adresses (try only if you're freakingly rich and only motive you're left with in life is to empty his quota xD)
Idk atm will tell if i learn something more or someone comments something

Can I call the google maps directions API from a web page (as opposed to a server)?

I am a long time programmer (C, Python, FORTRAN), but this is my first foray into javascript and anything web, so I am learning on the fly.
So, the main question up front: Can I use the google maps directions API from a script section of a simple web page on my laptop, or does it need to be called from a server?
I have an API key and I have successfully used parts of the API that are called as functions (Map, Geometry). I am trying to use the google maps directions API, which as I understand it, you must use via a URL and an HTTP GET. Here is a sample URL that my code has constructed:
https://maps.googleapis.com/maps/api/directions/json?origin=45.0491174%2C-93.46037330000001&destination=45.48282401917292%2C-93.46037330000001&key="my key"
If I paste that URL into the address bar, it works. I get a document back with the directions info. If I execute it from inside a script section on a simple web page I am building, the response I get is:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
I did some searching, both in stackoverflow and elsewhere on the web and I came across this:
http://www.html5rocks.com/en/tutorials/cors/
Per that page, I checked to make sure that withCredentials was supported and then I set withCredentials to true. This did not alter the outcome. Obviously, the API works, so I am now wondering if I have to do this from a web server and not from a simple web page to get around the cross-domain limitations. I am hoping to avoid having to set up a server since this is a one-off for my own personal use, but maybe I dont have a choice?
As an aside, does anyone have any insight into why the directions API is called via a URL rather than as a javascript function like many of the others?
For JavaScript better use the Web -> Maps JavaScript API. This helped me solve this issue without a server.
The problem is that your Web Services -> Directions API unlike e.g. the Web Services -> Geolocations API, does not provide JS XSS functionalities like server side access-control-allow-origin: * response headers or JSONP functionality. Maybe this is even a bug of Google because it seems very strange to me that one "Web Services" API server does allow JS XSS and another not.
See https://stackoverflow.com/a/26198407/3069376
To answer the main question, Yes. You can definitely use the GoogleMap Directions API inside your web page. To get you started quick and easy, follow this link . Then,
Click on the JAVASCRIPT + HTML version, copy the whole code and paste it into a text editor and save it as an html file.
Start your own local server (like node.js). Dont forget to obtain a Browser API key and set your HTTP refferer (example http://localhost:4567) in Google Developer Console or you will get errors.
Run your html file on your local server (example http://localhost:4567/myprojfolder/samplewebfile.html) .
You can do this with all Google Maps JavaScript API samples. If you're curious about setting a node.js server, there are plenty of resources online.

How to secure the JavaScript API Access Token?

There are numerous online resources which provide JavaScript APIs to access their services. To be more clear, I will base my question on the example of MapBox, but this applies well to many other services in various domains.
When someone wants to use such a service in a web application (like the map imagery from MapBox for example), they typically need to Register/Sign Up and obtain an access token to access the service.
Now, if I would use the API from the server side - there is no issue: I know my token is stored securely somewhere on the server and is only exposed upon communication between my server and the service provider, which is OK as long it is HTTPS. However, in case of a JavaScript API (for example if I use Leaflet to render a map from MapBox), I am supposed to have my access token in a JavaScript which is exposed to the user's web browser - and so it makes it extremely easy to find someone's access token. My users, or in a case of a public service, literally anyone, would be able to find the token in the browser's "Dev Tools".
This token however, as for me, should be considered as a sensetive data - service usage is tracked based on the authentication this token provides. If you pay for the service based on its usage it becomes critical, but even if you don't (like, if you use a Free/Starter/Non Paid plan) - service usage is limited and I'd like to be sure it is only me who uses it.
Is my only option a proxy via my own web server?
Is there a way to secure the access token used by a JavaScript API to access an external service, provided that JavaScript is executed in a user's browser?
Restrict Access with CORS
Make your web server return the access tokens on an ajax request from you javascript with CORS setup. Token can be captured with this method visiting your app.
Provide Tokens to Authorized Users
You can also add authentication on your webserver to provide limited access to the users you allow. Token can be captured with this method but only by authorized users.
Proxy Requests
The only way to completely protect that token is to proxy the requests through your server. Token cannot be captured with this method. Note that this may be against terms of service.
Javascript API tokens (and all client tokens, in fact) are always visible to the client (unless using them only server-side, as in node). There is no way around that. As you mentioned, the only way to truly secure an API key and keep it private is to store it in the server, then request the server to make the request on the client's behalf.
5 years later, this is not necessarily for the original poster but for anyone still interested, Mapbox now allows you to easily restrict tokens by domain(s):
https://account.mapbox.com/access-tokens (assuming you are signed in)
I will speak only about map imagery APIs like Mapbox, it seems that unfortunatly only services like Google Maps, Here Maps, Bing Maps etc offer ip/domain filtering by service provider or this type of security, all offers based on OSM i met don't propose it. As Justin Poehnelt said the only reliable way is to build a proxy, but it's usually forbidden. I find this in the ToU of Mapbox:
You may not redistribute Map Assets, including from a cache, by
proxying, or by using a screenshot or other static image instead of
accessing Map Assets through the Mapping APIs.
You may like to read up on CORS headers
These allow you restrict which domain can call a remote web service.

Is it possible to connect the Google Maps API through reverse proxy in my app?

I am working on an app where I want to use the Google Maps API.
The problem is the connection to Google Maps API server is unstable. Sometimes it's OK but other times it's blocked because I'm in China.
The solution I've come up with is to make all the Google Maps API requests through a reverse proxy. I can setup a server as a reverse proxy in American or Hong Kong where there is a steady connection to Google maps server.
Then I have to change the urls of all the Google Maps APIs in my app to point to my reverse proxy and the proxy will proxy_pass all the requests to Google Maps server.
There are a few questions I have about this:
How would I go about implementing the client side libraries? Do I have to change them? If so, can I just download the Google Maps JavaScript API file and change the domain names of the urls in it to the domain of my proxy server?
And how would I go about Android and iPhone apps? I'm uncertain whether the Android and iPhone SDKs will make the request with http protocol. If it is, how can I replace the domain names of the APIs with the domain name of my proxy server?
I thought maybe there is a way to catch all the http requests made in my app and modify them before they get sent but after googling for a while I've found it's hard to do.
So is it possible to do this with Android and iPhone apps? Or is there a better way to achieve it with a web app?
I also would like to know is it worth the effort to do this since the solution seems to be rather complex and using the Google Maps API is not a necessity because there are replacements to it in our country. I just prefer Google Maps API to them because of its neat API style and the prettier look of maps.
Your solution is a blatant violation of Google's terms and conditions.
10.1.1 (a) You must not access or use the Maps API(s) or any Content through any technology or means other than those provided in the Service, or through other explicitly authorized means Google may designate.
For example, you must not access map tiles or imagery through interfaces or channels (including undocumented Google interfaces) other than the Maps API(s). https://developers.google.com/maps/terms
Legal issues aside, I think you answered your own question. "Google Maps API is not a necessity because there are replacements to it in our country".
But if your hell-bent on using Google Maps you can use their tiles with a 3rd party library like leaflet for web content. Native mobile apps are an entirely different problem though...one which I suspect is either a: not possible or b: not feasible.
FWIW, this doc from Google states it is acceptable to cache map images.
https://developers.google.com/maps/premium/optimize-web-services#cache
Significant correction to the accepted answer:
The cited section 10.1.1 no longer exists. Moreover, searching for the terms "authorized" or "other than" in the Terms & Conditions (T&C) returns no hits for a similarly worded replacement.
In conclusion, upon reading the T&C it appears that Google no longer explicitly says You must not access or use the Maps API(s) or any Content through any technology or means other than those provided in the Service nor does Google appear to provide a replacement.
T&C here: https://cloud.google.com/maps-platform/terms/
There is a Google Lab to use the Google Places API: Google Maps Web Services Proxy for Mobile Applications
It seems that this is the repo: https://github.com/googlecodelabs/google-maps-web-services-proxy

How to communicate securely (with proper authentication) to a 3rd party api on the client?

Consider the usecase in which a website uses a paid analytics package to track user behavior on said site.
In that case the website needs to securely communicate with an API of the analytics provider (all clientside through javascript).
How can this be done securely? To my understanding of the various authentication protocols a secret token is always needed to setup a secret-handshake between client and server. Using oAuth1a this is all packed in HMAC, etc. but still the secret must be available.
Given that:
the secret code must be available to the client in javascript to do authenticated calls
javascript on the client can obviously be inspected by anyone
How would you keep the secret safe? It seems you can't, but how then do all these paid 3rd party services which communicate through clientside JS keep things secure?
As stipulated by the referenced answer below, it seems Google Maps API is doing this with the HOST header which apparently (?) can't be spoofed.
How does Google Maps secure their API Key? How to make something similar?.
Thus, having a sever-side map which uses a map of <apikey -> allowed HOST headers> would do the trick.

Categories

Resources