0

So I want to have nginx serve up my react app that uses an API that is setup to make all the API calls for me. I want to do this so I can guard my API key and secret. So the API server is running on port 9001 and my react app is making api calls to to http://localhost:9001/api/v1/token. It works just fine. The issue I have is, how can I stop someone from doing the following to get a token?

curl -X POST --header "referer: http://localhost:8081" -i http://localhost:8081/api/v1/token

Thanks

jrock2004
  • 3,229
  • 5
  • 40
  • 73
  • It's not clear what you're trying to prevent from happening. You want someone to be able to get a token from their browser but not from curl? – azium Apr 25 '18 at 23:52
  • @azium I want to stop people from faking like they are the nginx server and getting a token when they are not suppose to – jrock2004 Apr 25 '18 at 23:57
  • What do you mean by "are the nginx server" ? When you make a request from your React application, that request doesn't come from the nginx server it comes from the browser. All the nginx server does is send that static files (html / js) to the browser, then javascript running on the browser makes the request, no different than curling it – azium Apr 25 '18 at 23:59
  • @azium what would happen if I had a nginx-proxy. Would that not mean that it would go back to the nginx server first? – jrock2004 Apr 26 '18 at 00:02
  • sure you can create a labyrinth of proxies if you want but if you want your client side application, your react application to make requests to it, then you're also allowing people to curl it – azium Apr 26 '18 at 00:03
  • 1
    This is why, typically, apis require clients to log in before requesting resources which are not public – azium Apr 26 '18 at 00:07
  • 1
    @azium Then I guess you would have to just put limits to protect yourself. Thanks – jrock2004 Apr 26 '18 at 00:10

1 Answers1

3

If what you're asking is how you allow only your react app to use your API server, then the answer is you can't really.

Any request made from the browser has to be made to a server that can be reached lots of other ways (such as your Curl example). You can't allow only requests made from your React code and disallow all other attempts to talk to your API server because at the lowest level, these are all just http requests. Any determined hacker can just watch what the browser sent from your React app and make an http request that looks just like it. This is a fundamental design characteristic of how apps in a web browser work.

That said, there are some things you can do to "protect" your API server from abuse.

1. Require some form of account or authentication. This will at least require a hacker to make an account in your system and use that account to access your API server (more on this later).

2. Implement rate limiting so that an individual account (detected based on the credentials in the previous step) is only allowed certain frequency or pattern or access. At the very least this protects your API server from being overly abused by one bad actor.

3. Implement abuse control. If one particular account is regularly abusing the API server (hitting rate limit controls and generally using way more resources on your API server than any reasonable normal browser user ever would), then you can ban that account.

Services such as Google maps implement all three of the above in their efforts to protect the integrity of their API servers.


There are other techniques such as embedding an ever changing token into the web page that is then required with each subsequent call to the API server, but a determined hacker will just scrape the token from the web page and then use it until it expires so this is really just another obstacle for the hacker to get around, not an actual roadblock.

jfriend00
  • 683,504
  • 96
  • 985
  • 979