1

I know this is a really common question, and lots has been written about it. Despite reading a lot online however, I can't find a suitable solution.

I have a fully public website - there is no login/secure area. The whole site is powered by API calls to various 3rd party websites. The site uses React on the front end. React needs to make API calls to power the website.

The problem is therefore, protecting the API keys.

Naive solution 1.

React makes API call direct to the third party API - something like https://api.someservice.com/endpoint?key=API-KEY

Clearly this is no good because it exposes the API-KEY.

Solution 2.

Everyone suggests creating a service on your own server, and make the API call to the third party from there. That way you don’t have to expose the API-KEY. So React makes a call something like https://api.myserver.com/endpoint

This service would then call the third party service, and return the result. The problem is, that someone else could just call the endpoint hosted on my server, and use it - effectively using my API-KEY.

So, the question is, how can I make sure I (my React app) am the only person who can call the API service hosted on my server?

----Edit with additional information.----

Basically a map is displayed with information overlayed. As the user scrolls the map, API calls are made asynchronously and information relevant to the displayed location is superimposed onto the map. There's no input form, no submission, just a constant stream of asynchronous API calls as the user navigates the map.

I need to protect those API calls. There's no form submission, or login/authentication of any kind. This site is open to everyone.

Cardinal System
  • 2,749
  • 3
  • 21
  • 42
swalesong
  • 23
  • 1
  • 5
  • 2
    I'd suggest looking into CSRF (Cross-Site Request Forgery) prevention, I think it would help to address some of your concerns. – CollinD Feb 06 '18 at 20:39
  • This may help you https://stackoverflow.com/questions/2392100/how-to-prevent-csrf-in-a-restful-application – Richard Elite Feb 06 '18 at 20:45
  • Note: The entire point of authentication and authorization is to ensure that only certain people can access things.. – cHao Feb 06 '18 at 20:52
  • Well if you put it on the backend you can make sure the calls are coming from your domain. But it would not stop someone from popping open the console and running scripts against it. – epascarello Feb 06 '18 at 21:04
  • @CollinD - this is what everyone seems to say. I can understand if you've got a form, and you want to make sure you protect submission, then CSRF makes sense - and is easy. Use something server side like PHP to add a token to the form, then when it submits the server can check the token. I'm not submitting a form in my case - I've edited the question to add a little more clarity – swalesong Feb 06 '18 at 21:15
  • @ManojKrishna Double Submit Cookie looks interesting, but again, someone could create a valid session and a valid secure cookie, then make arbitrary calls to my API service. I don't see how I can stop that. – swalesong Feb 06 '18 at 21:16
  • @cHao - sorry, I don't understand this. My site doesn't have any authentication. I agree about authentication and authorization - I want to make sure I am the only person who can make API calls to my 3rd party service using my API-KEY :) – swalesong Feb 06 '18 at 21:16
  • @epascarello - my thoughts exactly!! Doesn’t really sound satisfactory - could get quite expensive for me if some wants to abuse it. – swalesong Feb 06 '18 at 21:16
  • 2
    So that is why you look into limiting requests via ip and all of that wonderful junk.... – epascarello Feb 06 '18 at 21:17
  • @ManojKrishna What on earth are you talking about. Of course I can examine the body of a post. Please remove that dangerous comment. – gforce301 Feb 06 '18 at 21:35
  • @swalesong: You are having this problem *because* you have no authentication. If your service's users had usernames and passwords, you'd have protection from random strangers...plus the ability to see per-user statistics. – cHao Feb 06 '18 at 21:49
  • The API Key from Google, etc is supposed to be a *public* identifier of your app, and as such doesn’t need protection, you can configure API keys to be usable from specific domains only so they are useless outside of those domains. You seem to have another problem of an open personal web server that folks are using - thats another kettle of fish. – James Feb 06 '18 at 22:05
  • @James: So how do Google stop people outside a specific domain using a given API key. Let's say Google has an endpoint called 'get_location_info' which takes three parameters: lat, lng, and api-key. I could call the service something like [link](http://api.google.com/get_location_info?lat=51.508341&lng=-0.125499&api-key=XXX) How do Google make sure I can only call that service from my domain? – swalesong Feb 07 '18 at 06:50
  • @James I don't see that I have an open web server. I have a website I want everyone to use without having to log in (like Google Maps for example), which has an additional overlay of information. To display that information I have to call an API service to get that detail. I don't get what is odd or wrong about that. In fact, I can't believe I've never had this problem before - it sounds like one which should definitely be solved. I'm surprised no one has written a blog post/posted an answer specifically for this use case before. – swalesong Feb 07 '18 at 06:54
  • When a request makes use of your api key, Google checks the request to make sure it originated from your domain, or the request is denied. That can be configured under “restrictions” for your api key. – James Feb 07 '18 at 13:45
  • @James: this interesting question though is **how**. Looks likes this is old ground though - https://stackoverflow.com/questions/2256305/how-does-google-maps-secure-their-api-key-how-to-make-something-similar - where the consensus is basically that it's somewhat best efforts. Trying myself today I can forge requests against my own Google API key by spoofing the site it's meant to be locked to. I think I'm coming to the conclusion that all I can do is make it awkward to spoof (like Google does) and accept that someone determined might be able to do something I'd rather they didn't. – swalesong Feb 07 '18 at 18:00
  • It’s easy to steal an api key and spoof the referer header from your own pc with postman or fiddler. Its hard to create a website that uses a stolen api key, because clients visiting that website use a browser rather than tools like fiddler that can change the referer. – James Feb 07 '18 at 18:24

1 Answers1

0

I'm running into the same issue as you and what I'm planning to do is to use dotnet core with SPA and server-side rendering. In my case, I'm using Angular but they do have ready to use templates for react and react + redux.

With this combination, your react app will run inside your MVC app. This means you can have a proxy API that will only take requests from localhost (remember you have SSR) and from that API controller you can call the other API. your keys will be safe since they will be used only by your C# controller which is your man in the middle. The actual exchange of information will be done between servers

(Source)

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135