Get access to DocumentDB with JS - javascript

I'm developing an app, which should connect to an external DocumentDB database (not mine). The app is build with Cordova/Ionic.
I founda JavaScript library from Microsoft Azure in order to ensure a DocumentDB database connection, but it is asking for some weird stuff like collection_rid and tokens.
I've got the following from the guys of the external DocumentDB database:
Endpoint: https://uiuiui.documents.azure.com:443/
Live DocumentDB API ReadOnly Key: P8riQBgFUH...VqFRaRA==
.Net Connection String: AccountEndpoint=https://uiuiui.documents.azure.com:443/;AccountKey=jl23...lk23==;
But how am I supposed to retrieve the collection_rid and token from this information?

Without row-level authorization, DocumentDB is designed to be accessed from a server-side app, not directly from javascript in the browser. When you give it the master token, you get full access which is generally not what you want for your end-user clients. Even the read-only key is usually not what you want to hand out to your clients. The Azure-provided javascript library is designed to be run from node.js as your server-side app.
That said, if you really want to access it from the browser without a proxy app running on a server, you can definitely do so using normal REST calls directly hitting the DocumentDB REST API. I do not think the Azure-provided SDK will run directly in the browser, but with help from Browserify and some manual tweaking (it's open source) you may be able to get it to run.
You can get the collection name from the same folks who provided you the connection string information and use name-based routing to access the collection. I'm not sure exactly what you mean by token but I'm guessing that you are referring to the session token (needed for session-level consistency). Look at the REST API specs if you want to know the details about how that token gets passed back and forth (in HTTP headers) but it's automatically taken care of by the SDKs if you go that route.

Please note that DocumentDB also provides support equivalent to row-level authorization by enabling you to create specific permissions on the desired entities. Once you have such a permission, you can retrieve the corresponding token, which is scoped to be valid for a certain time period. You would need to set up a mid-tier that can fetch these tokens and distribute to your user application. The user application can then use these tokens as bearer-tokens instead of using the master key.
You can find more details at https://msdn.microsoft.com/en-us/library/azure/dn783368.aspx
https://msdn.microsoft.com/en-us/library/azure/7298025b-bcf1-4fc7-9b54-6e7ca8c64f49

Related

Where to "hide" an API key

My question is about where and how to:
hide an API key
access the hidden API key in my app.js file
In this case I am dealing with an Algolia Admin API Key (but aiming to ask this question in a fairly generic way).
In order for my app to work, based on certain user actions I need to update my Algolia index (which requires an Admin API Key in order to do).
I understand that I am not supposed to expose my Admin API Key to the front-end (i.e. don’t put it in my app.js file). How can I securely pass my API Admin Key to my app.js file, so that I can make updates to my Algolia index?
Some things I've come across:
-Should I hide it in a config.json file? I can't figure out how use information exported from a config file in my js (which maybe would defeat the purpose anyways?). I read this
-Also on the Firestore docs it mentions, in reference to working with Algolia, that "App ID and API Key are stored in functions config variables". How do I store my API key in config variables?
-I read this about using environment variables, and exporting them to the app.js file. But if I then push the app-env file to the server (which I assume I'll need to in order for the app.js file to read the API key) how is that more secure than just putting it in the file?
You cannot give the key to the client, through any mechanism, and keep it secret.
Build a web service (in your server-side language of choice, with whatever authentication is appropriate) and write your own API to allow a limited selection of actions to be performed. Your web service then acts as a client to Algolia.
After doing a bit more research this is what I've decided.
I need to create a separate .js file that contains the Admin API Key and the function that listens for changes in my database, and makes the appropriate updates to Algolia (that's pretty obvious).
Next I need to get that file to run. I believe I have two options:
Run the file locally. This is secure because the file is not being served anywhere beyond my local machine. The main drawback here is that I'd basically have to keep the file open all the time, which would quickly become impractical in production.
Host my file somewhere like Heroku, Nodejitsu, so that it can run perpetually on their server.
Private Server
We can hide an API key/secret, here, for example, Algolia Admin API Key by creating a separate private server.
The private server can be kept private to yourself or the development team.
We can send an API request to the private server.
And the app/website will use the API key/secret and perform the necessary actions.
Later, send only the necessary data back to the app/website as the response.
This way the API is hidden from the user.
This approach provides a layer of abstraction over the API key/secret as well as the functionalities which uses the API key/secret are associated with the logic

Securing JS client-side SDKs

I'm working on a React-Redux web-app which integrates with AWS Cognito for user authentication/data storage and with the Shopify API so users can buy items through our site.
With both SDKs (Cognito, Shopify), I've run into an issue: Their core functionality attaches data behind the scenes to localStorage, requiring both SDKs to be run client-side.
But running this code entirely client-side means that the API tokens which both APIs require are completely insecure, such that someone could just grab them from my bundle and then authenticate/fill a cart/see inventory/whatever from anywhere (right?).
I wrote issues on both repos to point this out. Here's the more recent one, on Shopify. I've looked at similar questions on SO, but nothing I found addresses these custom SDKs/ingrained localStorage usage directly, and I'm starting to wonder if I'm missing/misunderstanding something about client-side security, so I figured I should just ask people who know more about this.
What I'm interested in is whether, abstractly, there's a good way to secure a client-side SDK like this. Some thoughts:
Originally, I tried to proxy all requests through the server, but then the localStorage functionality didn't work, and I had to fake it out post-request and add a whole bunch of code that the SDK is designed to take care of. This proved prohibitively difficult/messy, especially with Cognito.
I'm also considering creating a server-side endpoint that simply returns the credentials and blocks requests from outside the domain. In that case, the creds wouldn't be in the bundle, but wouldn't they be eventually scannable by someone on the site once that request for credentials has been made?
Is the idea that these secret keys don't actually need to be secure, because adding to a Shopify cart or registering a user with an application don't need to be secure actions? I'm just worried that I obviously don't know the full scope of actions that a user could take with these credentials, and it feels like an obvious best practice to keep them secret.
Thanks!
Can't you just put the keys and such in a .env file? This way nobody can see what keys you've got stored in there. You can then access your keys through process.env.YOUR_VAR
For Cognito you could store stuff like user pool id, app client id, identity pool id in a .env file.
NPM package for dotenv can be found here: NPM dotenv
Furthermore, what supersecret stuff are you currently storing that you're worried about? By "API tokens", do you mean the OpenId token which you get after authenticating to Cognito?
I can respond to the Cognito portion for this. Your AWS Secret Key and Access Key are not stored in the client. For your React.js app, you only need the Cognito User Pool Id and the App Client Id in your app. Those are the only keys that are exposed to the user.
I cover this in detail in a comprehensive tutorial here - http://serverless-stack.com/chapters/login-with-aws-cognito.html

How to add database system to WebGL application

I'm currently working on a WebGL sketch drawing project where users can draw arbitrary objects on an html canvas. The javascript libraries and files are all stored on a node.js server which is currently being started up locally every time the software has to be run. Essentially all of the functionality for saving all of the drawn objects on the page has been implemented where the drawings are being written as JSON objects, but the next step is to persist these objects to a database where they can be mapped to a user id. I will also need to implement a login system where users will login and be able to select previously drawn objects to edit from the database.
If this was just a normal website, I would probably just use express.js or something similar, but as the views are essentially rendered entirely in WebGL, I wouldn't think that frameworks would work well with this construct.
Given that I currently just need to create a login system and implement a feature for persisting the JSON object to the DB, are there any frameworks or existing software that accommodates the specified needs of the system?
With regard to authentication, I would recommend taking a look at OAuth and using existing identity providers (e.g. Google, Facebook, etc). You can still retain profiles for your users but you don't have to deal with all of the intricacies of authentication, authorization, security, etc.
There are a ton of JavaScript libraries out there for handling OAuth/OAuth2 interactions. Some even have built-in identity providers. Here are a couple links that returned all sorts of potentially useful libraries:
https://www.npmjs.com/search?q=oauth2
https://www.google.com/search?q=javascript%20oauth2%20library
As for a database, you have a lot of options for storing raw JSON. Some that I've used recently for my JavaScript projects are PostgreSQL, MongoDB, and ArangoDB. You can find well written JS libraries for interacting with any of those.
Another thing to think about is if you want to install the database on your server or use a hosted solution such as RDS or DynamoDB (available from Amazon).
Regardless of the exact authentication and persistence options you choose you will likely use a pattern similar to this:
Your Node.js server is deployed somewhere accessible on the internet, where it exposes the endpoints for your WebGL application, authentication, and saving/loading sketches.
When the user navigates to the WebGL application endpoint on your Node.js server they are required to authenticate (which will utilize your authentication endpoints on the Node.js server).
When the user requests a "save" in your WebGL application you will submit the JSON representation of their sketch (and their authorization token) to the "save" endpoint of your Node.js server.
This "save" endpoint validates the user's authorization token and inserts the JSON into whatever database you've chosen.
The "load" endpoint works just like the "save" endpoint but in reverse. The user asks for a specific sketch. The identity of the sketch (id, name, etc) is sent along with their authorization token. The "load" endpoint on your Node.js server validates their authorization token and then queries the database for the sketch.
The key pattern to notice here is that users don't send requests to your database directly. Your WebGL application should communicate back to your Node.js server and it should commmunicate with your database. This is essential for controlling security, performance, and future updates.
Hopefully this gives you an idea of where to go next.
EDIT based on comments:
I searched around for a Node.js + PostgreSQL guide but didn't find anything I would feel comfortable recommending. I did find this JS library though, which I would check out:
https://github.com/vitaly-t/pg-promise
For MongoDB I would just use their official guide:
https://docs.mongodb.org/getting-started/node/introduction/

how to secure parse initialize with app and secret?

I'm setting up parse framework in javascript. I notice that I need to call
Parse.initialize("app", "secret")
Since this is in the page source, couldn't anyone take this and make calls against my account?
Is there a more secure way to store this info?
As per Parse Security Guide your JavaScript key is NOT secret:
When an app first connects to Parse, it identifies itself with an Application ID and a Client key (or REST Key, or .NET Key, or JavaScript Key, depending on which platform you're using). These are not secret and by themselves they do not secure an app. These keys are shipped as a part of your app, and anyone can decompile your app or proxy network traffic from their device to find your client key. This exploit is even easier with JavaScript — one can simply "view source" in the browser and immediately find your client key.
So yes, anyone who found your key can make calls.
But you can (and should) restrict what such anyone can do.
Using Class-Level Permissions you restrict what can be done with individual classes.
Using Object-Level Permissions you restrict what can be done with selected objects.
See also Roles and Roles Hierarchy for simultaneously setting permissions for a group of several users.
For instance, you can restrict access to only specific users. Only if one of those users is logged in, the access is granted. Any other "hacker" can try to use your keys but the request will be rejected by Parse.

How to make a web API private

I have an API that I would like to restrict access to. I can provide access keys and check them with each request, but I'm not sure how far this is really going to go.
The API is used by applications, but it is also used by a web app which someone can just view the source of. If they did, they would have the key and could easily make API calls.
Is there a more reliable way to secure access? I'm not sure what the standard practice here is.
Edit: After thinking about it, I could use a two-prong approach. The web app can use POST with CSRF, and applications can use API keys. Any other ideas, or is this a generally accepted solution? (Note, this still wouldn't work for third-party web apps.)
Your API is never private since it's used by a web app which I am assuming is available to the general public. If this is the case, there really is no impetus to secure it since anyone and everyone would have access to the API.
If on the other hand, this web app is only available to registered users, you can use a token system to check for authorization. When the user successfully logs in, you pass back a token (usually something 20 to 30 characters long). Every API request would require a valid token. Tokens can be set to expire automatically (using a database job) X hours after creation if your application requires higher security thresholds. If security isn't a big issue, they can be renewed automatically every time a request is made.
This is essentially a two tiered approach. Temporary tokens are generated for users to directly connect to your API so that permanent credentials are never sent to the client. Predefined keys are given to third party developers who build applications on top of your API and have their own back-end.
If it's your API you can simply do this.
1) Insert the following code into your API file(s)
$authToken = "APItoken"; //variables
if( !isset($_REQUEST["authToken"]) || $_REQUEST["authToken"] != $authToken )
die("Need auth token");
2) You will now need to GET/POST/PUT the URL like this:
http://www.yoursite.com/api1.php?authToken=APItoken&nextParam=&paramAfterThat=
If this helped please mark it as the answer
EDIT:
Nevermind, read it wrong. Updating answer in a few minutes.

Categories

Resources