38

So, I'm developing a small application just for my own use and perhaps an open source project on Git. I'm using an API from Envato Marketplaces, and as you all know there are some operations that don't require any keys, but in the same time there are some that do require.

I first made a nice API wrapper for the Envato API in PHP, but then I decided to experiment a little bit with JavaScript, so I'm developing the same wrapper with JavaScript. So far I have no problems with the public operations, but I now have to use the API Key.

My question would be if there's a way to protect the API Key in JavaScript. I cannot just put it there in plain text as it can then be used by others who see the code. So would there be an implementation where the API remains secret ? Maybe grabbing it from a JSON text file with XHR ?

7
  • 3
    Have your javascript calls interact with the server side php to call the methods that require privacy. Commented Jul 13, 2012 at 12:23
  • 2
    @asawyer: you should put that as an answer Commented Jul 13, 2012 at 12:26
  • @asawyer - That's the thing, I'm already doing it with PHP, now I'm trying to do it only with JS. So doing it with JS only would be impossible ? What if I make a call which grabs the key from a JSON file with XHR and then pass it to the method ? Commented Jul 13, 2012 at 12:27
  • 1
    It would still be easily found using javascript debugging tools Commented Jul 13, 2012 at 12:28
  • You can't protect the API key if it's going to be used in JavaScript. My advice is to declare and define a variable API_KEY as a config option. Add a comment // Put your API key here (get it at http://....), so that developers who want to use your wrapper can use it. Commented Jul 13, 2012 at 12:29

4 Answers 4

35

Short answer: No

What ever you do to obfuscate the key, you still have to send it to make it available on the client somehow, and therefore it will be possible to extract it using fx. Firebug.

Even if you devise an awesome magical way to keep the key secret, at some point you would have to make the actual API-request, and as it would have to be sent from the browser, an attacker would be able to read out the key in plain text from Firebugs net tab.

The right thing to do is to create a PHP wrapper around the API calls that require keys, and then call that wrapper from Javascript.

Sign up to request clarification or add additional context in comments.

6 Comments

The key will be protected but the operation won't. A thief doesn't need the key if the door is left open.
Can the PHP wrapper enforce that requests originate from the same domain? What's the relation of this to "same-origin policy"? Looks like it's not reliably doable to determine requester: stackoverflow.com/questions/1153967/… ...?
How would the wrapper change anything ?
@SteffenChristensen, a wrapper in PHP (or some other server-side language) runs on the server, not in the browser. This avoids having to send your API key to the browser at all.
@m3h0w, the server-side functionality can (and should) be properly secured, e.g. by using a TLS connection, requiring authentication, including an authorization layer, logging properly, using CSRF protection, etc. The point is that you control your server (the extent to which this is actually true varies depending on your hosting environment, but it's good enough for now), but your user controls what happens in their browser. Protect your API keys by keeping them where you have control, and exercise that control to ensure that they are used correctly.
|
2

My solution right now is to write a little wrapper in rust, and throw it in the /cgi-bin and make calls to that. That should keep the api-key, api creds and session data separate from the client.

Comments

0

While using JS, there are two environments your code usually executes within - client(browser) OR server(node).

For the API key to remain a secret you need to ensure it never reaches the client in the first place. Any code reaching the client can be debugged easily for API keys etc.

So, how to achieve API key hiding?

Store the API keys on the backend and have the backend make the request for you.

e.g. Instead of directly interacting with a 3rd party API from the client / front-end like so:

axios.get('https://api.some-weather api.com/weather?lat={lat}&lon={lon} &api_key={API_KEY}`)

you can just call your backend's API that can make the call to the 3rd-party API like so:

axios.get('https://api.your-project.com/ weather?lat={lat}&lon={lon}`)

your backend api can then call the 3rd-party API with the API key that's stored via an env file(exists only on the backend):

axios.get('https://api.some-weather api.com/weather?lat={lat}&lon={lon} &api_key={API_KEY}`)

this way you don't expose your API keys, they're not included in the build of your web app so they won't be seen in developer tools.

As soon as you try and use env vars directly in the frontend code, you are exposing them to the web. Usually via the bundler tool/ecosystem that will lift the env var out of the .env file and bake the value into the bundled frontend code.

Note: Since you mentioned open source, I’d also add that it is good practice to have environment specific data and secrets to NOT go directly into source control.

Env variables (with .env files that are gitignored) mainly hides it from other developers in the source code, like the git repo and perhaps deployment logs.

1 Comment

Sure, this doesn't expose your weather API key, but you probably want to add some other client authentication (e.g. using a session cookie) or else you'll have opened up a pretty big hole where anyone can make their own weather requests through your server using your API key.
-2

The session context is a bit lost concept. However, if your Async request calls your server where your active session can be tracked then before the server makes an API call then the server can add a mapped API key for that request while sending the request to the service provider. The service provider can validate the domain from where the request is received and this will be a more effective way to protect API key and request spoofing.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.