Protecting API Key in a JS application - javascript

I am new to JavaScript.
The help I wanted was to understand how to protect API Key used to access my Restful web services.
I am accessing some Restful web services using API keys and I want those API keys to be protected. As when I put API keys in Controllers they will be visible to users since Javascript code can be seen by the end user.
Is there anyway that I can register these as some variables and use in Controllers where end user who view the Javascript code cannot see API Key?
Thanks in advance!

if you need to protect anything do it on the server. You can proxy api calls on the server for instance, but there's no way you can protect anything with client side javascript code.

You are absolutely confused.
You are trying to achieve security by obscurity.
Everything that is on the client is transparently hackable.
The user should only be allowed to access a resource after a successful authentication and authorization. Period.
So you must store your API keys on the server if they are supposed to be secret (like provided by Facebook, ...)
(btw: remove the angularjs tag).

I am using AngularJS together with PlayFramework and seems like I can solve the issue as external web servcies/API's are accessed through Play controllers where controller methods are accessed by AngularJS model with
jsRouter.controllers.Application.tasks().ajax
So, the external API keys doesn't have to be in AngujarJS models.
Thanks all for help.

Related

How do I use APIs with access tokens in apps created with create-react-app

How do I hide an API's secret access tokens in a production build of an app created with create-react-app?
I've visited this question but it does not have an acceptable answer to my question. I do not want to use process.env.REACT_APP_SECRET_VALUE in my app as this variable would be exposed in the client-side javascript.
Given that the production build of a create-react-app app is composed of static files only, the only solution I can think of involves only using APIs that use a combination of public client IDs and some form of backend client whitelisting, IP or otherwise.
Am I missing something here?
Like you already mentioned, you can request an api backend that only returns your secret if it's whitelisted IP.
But still can you be a litle more specific what are you trying to achieve, just guessing but maybe you need to look at direction of some authentication first so after that the user on the client side would be able to do something (see secret).
You're on the right track. If you're unwilling/unable to expose keys for services you're using, you may need to create an endpoint on a server somewhere that you call and have that endpoint proxy the relevant API request. Amazon's API gateway could probably handle this for you.
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-usage-plans.html

Angular and secret keys

I have been learning angular 2 and have been doing research on how to protect data within my app.
How, if possible, can you obstruct data from the front end of the app? Is it possible to serve the angular app through a node server, say using Universal Angular, which would mean variable values can be hidden from the user on the front end.
I am essentially looking for the solution of hiding private keys which will give the app access to various APIs/creating auth headers/paths. I've read a solution is to have an API bridge for the app - so I would connect to that to retrieve the data/keys - but then how do I protect that from access? Since that endpoint would then be exposed and could be abused, or if getting keys the response is visible. The idea of locking down to domain I have read is unreliable due to spoofing and locking to IP wouldn't work as its front end or through an app?
I feel there is a glaringly obvious answer that I am missing something.
You must assume that everything that is held in your frontend is visible to anybody that can access your frontend.
All JS variables, storage (local, session), network requests, etc. in your front end are unsecured from users of your frontend.
You can (and should) use SSL to make hide data from anybody in between your server and the browser, but there is just no way to secure data held in your frontend from users of your frontend. (At least if your frontend is available on "regular" browser as opposed to some tightened kiosk mode installations.)
It's simple, when the server sends the data as response to a request, then the data can be accessed from the outside.
If you don't want that, then don't send the data.
You didn't mention what problem you actually try to solve. For API keys you can for example do the request to the API on the server and provide an API on your own server for your clients and then make the server forward the requests to the actual API server.

How to Secure ASP.NET Web API with Cross Domain AJAX Calls?

I want to create an API at www.MyDomain.com that is accessible from public websites www.Customer1.com and www.Customer2.com. These public websites display each customers inventory and do not have any login features. They will use AJAX calls to read data from my API.
How can I secure the API so that it can be accessed via AJAX from different domains but no one can access the API to be able to scrape all of my customers data and all of their inventory?
I have tried thinking of different solutions on my own but they would all either require people to login to the public websites (which isn't an option) or it would require some secret "key" to be displayed publicly in the browser source code which could then be easily stolen.
Any ideas would be greatly appreciated.
Thanks!
P.S. Are their any obstacles that I am going to run into using Javascript & CORS that I need to look into now?
Anything that is accessible without authentication from a browser is by definition insecure, so you can't stop that. Your best bet is to have to have a relationship with the owner of customer1.com and customer2.com - the server apps for those two websites would make an HTTP call to you and authenticate with your service. Going this way also avoids the CORS issues you're talking about.
If you've already designed the client functionality, you can still probably do it without much change to the javascript - have it point to customer1.com for its AJAX call instead of your API, and customer1.com would accept this request and just act as a proxy to your API. Aside from the authentication, the rest of the request and response could just be pass-throughs to your API.
You can use Microsoft.AspNet.WebApi.Cors.
It's just need add ONE line at webapi config to use CORS in ASP.NET WEB API:
config.EnableCors("*","*","*");
View this for detail.
The simplest way to provide a minimum security here is to provide some kind of token system. Each app has its own token, or combination of tokens which it must pass to the server to be verified. How you generate this tokens is up to you and other than being linked to app's access, doesn't have to mean anything.
Provide a way for each API implementer to open an account with you. This way you will know who is accessing what and in some cases you can block/stop service.
For instance, a token can just be an MD5 hash:
7f138a09169b250e9dcb378140907378
In the database, this hash is linked to their account. On each request, they send this token with what they want. It is verified first to be valid, then the request is fore filled. If the token is invalid, then you can decide how to deal with it. Either don't return anything or return an "access denied" (or anything you want).
One thing to avoid is having a single token for everyone, though this can be a starting point. The reason for this is if some unauthorized app gets a hold of this token and exploits it, you have to change the token for everyone, not just the app that somehow leaked the token. You also can't control if someone has access to something or not.
Since you listed ASP.NET, I can also point you to WCF, which is fairly complex but has all the tools that you need to setup a comprehensive web service to service both you and your clients.
I hope this gives you a starting point!
EDIT:
There are security concerns here in the case that someone leaks their token key somehow. Make sure that you setup a way in which the app/your service do not expose the the token in anyway. Also have a flexible way of blocking a token, both by your clients in you, if it so happens that a token is exploited.

Calling a web service from Javascript

What is the best way to add authentication / security while calling Web service from javascript ?
I want my web services should only get called from my application , anyone else should not be able to access my web service by copying web service URL into browser.
From the first few answers it seems like its next to impossible.
So what should I reply to my client as he is unaware of word impossible ?
~Ajinkya.
Have a look at using the synchroniser token pattern so that the service can only be consumed with a piece of data known to the page which loads the service reference. There's an example of doing this with a web service in OWASP Top 10 for .NET developers part 5: Cross-Site Request Forgery (CSRF). This should achieve what you're after.
This is not possible. If you allow a client to access your webservice from JavaScript, the client will always be able to do that. You can only reduce access by using some kind of constraint, like a Token that needs to be sent along with the request to authenticate it. You might even turn it into a one-time token. But this will create new problems (e.g. what happens if the answer gets lost. The client javascript cannot rerun the query).

What to do with unique API keys in JavaScript?

I am new to web javascript development and playing around with apps and scripts for some of the public API's around the web. When a site issues you a unique key to identify your application you code that into your script so you can access the sites API but then anyone who can visit your site can also inspect the source of your JavaScipt so they could see/take/use your API key.
While there's no direct security issue for your own site here, doesn't it mean that anyone else could take my API key and use it for their own app which is completely different? How does one go about making this secure or storing it in a secure way?
What is the best practice in this regard?
Generally API keys are tied to a domain. So even if someone tries to use your key it won't work on any domain but the one for the site it was issued for.
APIs typically offer domain authentication as an alternative to an API secret, for when the API needs to be called from client-side code.
Usually these KEYS are mapped to a domain. So another person's domain will not be able to use your key.

Categories