CouchDB and Cloudant Security - javascript

We have used CouchDB in production, mainly building apps in controlled environments. Most times, we use a middle-ware library to make direct calls onto couchdb/cloudant, hence avoiding direct (Front-End JavaScript calls direct onto CouchDB/Cloudant).
For security reasons, it is obvious that for an authenticated CouchDB database: http://{username}:{password}#IPAddress:Port/DB OR for cloudant: https://{username}:{password}#username.cloudant.com/DB ,
If the call is directly made from JavaScript, Developer tools in the browsers today enable a person to realise this call and hence has access to your database entirely.
Attachments are usually painful when handled in the middle-ware. It is advantageous to make cloudant handle the caching and serving of the attachments directly to the front end hence relieving our middle ware from that. However, on the web and with a huge audience, making direct calls to our cloudant environment is tricky.
We started out by first of all having a separate cloudant account for all attachments such that, an inquisitive boy will not tamper with the actual meta-data or information of our users. So, the only cloudant account they can have access to is that of the attachments since we are making direct JavaScript calls to our database.
Question: How do we find a way in which we hide the Username and Password of our cloudant environment thereby allowing us to securely make direct JavaScript calls onto cloudant ? Our infrastructure is entirely in the cloud, so we don't have proxies and stuff to work with. We have heard of Url shortening services, CDNs e.t.c. but, we have not come up with a really conclusive solution.

Try using the _session endpoint. This will set up cookie authentication.

How do we find a way in which we hide the Username and Password of our cloudant environment thereby allowing us to securely make direct JavaScript calls onto cloudant ?
As far as I know you can't do that without using a middleware or some kind of proxy. But that does not mean we are completely defenceless. couchdb gives us some spears to poke inquisitive boy :)
So a good thing that you have done is to make the attachments database seperate. You don't mention in your question if you are using couchdb authorization scheme so I going to assume that you are not. So the first step is to create a user in couchdb _users database and then assign it as a member in the attachments database. More details here and here.
After this step you should have a member on attachments database. The reason we want a member and not an admin is that members do not have permissions to write or read design documents.
It's a start but it's not enough since a member can still read via _all_docs and that is a dos attack right there. So the problem we face now is that we do this at the moment
https://{username}:{password}#username.cloudant.com/DB
A very good move would be to change it to
https://{username}:{password}#someurl.com/
What's the difference between these two? Well it hides the location of your database and makes accessing built in methods harder. This can be accomplished with the help of vhosts configuration and some rewrite rules. Some very good stuff is on Caolan's blog too
With this in place you have got two things going for you.
The stalker inquisitive boy will be clueless where the calls go to.
There will be no way he can get the contents of unknown documents by making direct calls. He can only access your database through the rules that you set.
Still not 100% secure but it's okay as far as read level security goes. Hope this helps.

Related

I want to limit the total number of articles read on my webpage by a user, without signup, like how medium does

I don't have any idea how to implement this. After a bit of search I found out that medium keeps track of the browser and not the user, what is mean is you can access three free articles from each new browser on the same machine (if I am wrong do point it out). I am using React and Firebase for my website.
Edit: I was thinking along the lines of getting some kind of id which is unique to a browser. As cookies and local storage can always be bypassed.
I don't know if it's a clean way to do it but you can associate an IP to an unique counter. Or with a cookie but he can bypass that by cleaning the cookies
The answer would tightly depend on your application setup and especially on the service backing your front store.
If you are using a self-backed backend, for example a nodejs - express based server, within your route middleware you can access the remote address from the req.connection.remoteAddress request property along with the user-agent req.header('User-Agent') and forward these to your datastore being Firebase in this case.
If you are deploying your application to Google Cloud Function, you can then access the remote peer address using the fastly-client-ip request header and still forward this to your storage system.
Use javascript and implement a system that uses a cookie or local-storage to verify how many articles are read on your website.
On most of these websites however you are still able to bypass this limit by clearing the cache or using a incognito window.
To also limit these scenarios you can use a cookie in combination with an IP address, which has its own drawbacks, especially in corporate environments, and mobile connections where IP addresses are heavily shared or changed. Depending on your situation this may matter or not.

Concept of a SaaS system

Good evening, I developed a system that behaves in the SaaS format, where the client only registers and already has access to use, in it I used a unique identifier for each client and they all use the same structure, PHP files and the same database . So far so good, because the domain does not change, that is, everyone uses www.lalalaetc.com.br/app and the system separates everything by the unique identifier, however, I would like to develop a virtual store from it, only there would be a difference, the domain, that is, I believe the principle is the same, use a unique identifier for each store, but my doubt is how I will make it so that when someone accesses the store the domain is addressed correctly and load the id of my client? What is the way forward and what do I need to research to do such a feat?
It sounds like you want to develop a multi-tenant application.
In this case, you could uses sub-domains, for example tenant.lalalaetc.com.br.app, where the word tenant is replaced with a string unique to each tenant.
When the request comes into the server, you can parse out the sub-domain, passing it to a function that searches your API/Database by this tenant subdomain.
i managed to handle the tenant with the folomming steps:
i cloned de the parse server source and i added a new middleware named "tenantConfig"
in that middleware i intercepts the requests and i get one specific header that i named "x-parse-tenant" and i use the value of that header like a database name
so i modify the datapase adapter and then resent it to the requetes and do next() to continue the process
so in the client lib or the requests i provide a "x-parse-tenant" header
you can see details in the screenshots
its not perfect i know :D

How sensitive is my identity pool id?

Background
I've been working on a front end javascript application that consumes AWS resources (mostly Lambdas behind API Gateway). The API Gateway resources are protected with IAM, and the app uses most of what Cognito offers accordingly.
This includes an Identity Pool with Unauthenticated Identities enabled, and federation with both a Cognito User Pool and multiple social and custom OIDC providers. Cognito is interacted with solely from our front end javascript code, using Amazon's SDK.
Unauthenticated Identities
The sensitivity of the ID pool id applies to all my use cases, but I'm most curious about the Unauthenticated use case. We've been following what seems to be Amazon's suggested approach: Use Cognito or STS to get IAM keys, and use those keys to access AWS resources. I've even been spreading this gospel.
This is all well and good, but it does require me to expose my identity pool id to the front end. And the identity pool id is the only thing you need to get IAM keys for your Unauthenticated IAM role.
Theoretically, any attacker could grab my identity pool id and start abusing my resources (that are allowed for the Unauth IAM role) using the same Amazon SDKs that I use.
The Question(s)
In a general sense, how sensitive should I consider an identity pool id to be? Is it just A-ok to show this to anybody?
If I decide it is sensitive enough to not expose to the browser, how do I deal with that? Where and how do I hide it and get to it?
In any case, should I "bake in" a way to rotate the id frequently?
Are there (types of) use cases where it's ok to expose the id, and cases where it isn't?
The answer(s) I'm looking for
As noted in the linked answer above, my understanding is that the Unauthenticated Identities thing isn't bulletproof, and only provides a reasonable level of confidence that it's your app on the other end of the line. In other words, while not impossible, it is at least reasonably difficult for someone to abuse your AWS back end using this model.
In addition to the bullet points above, I'd appreciate any critique of this understanding. Am I underselling the security around unauthenticated IAM access to AWS? Overselling it?
Disclaimers
I'll admit this question smells a lot like this one. I'm not asking about hard coding the identity pool id in my application; this is already fetched from a web service. However, it's still completely exposed to the front end, and you can argue that it's actually easier to pull it out of an AJAX response than out of minified code.
I do lock the Unauth role down as tight as I can, and I understand that allowing anonymous access to stuff can only be so secure.

How to make angular application safe if you need important vars and parameter?

I am still new to Angular apps and wonder about some security concerns and would appreciate some tips on how to handle this.
Lets say I access my Amazon S3 Server from my Angular Application. That for I need to write somewhere my bucketname, accesskey and secret key... but since it is all visible to the user everybody can see the secret key which does not make him anymore secret of course.
I can also not use something like a SALT etc. to create user passwords for the same reason. All is visible in the end and even with minify and uglify anybody can reverse it as well.
What is the best approach to do things like this? So far I can only think of one thing and this is to not use javascript or angular at all in this cases and for example only access my S3 bucket via PHP. But this cant be the only way I hope?
For Firebase it looks the same problematic since everybody can see all infos right away and can connect basically to my DB and than add for example information he want to. Of course I can setup rules and make certain things obligated but this can be also sniffed out easy inside my code at the end which seems all pretty unsafe if I compare this to a php/mysql backend.
You can use the Cordova SecureStorage plugin to store access and/or session tokens:
https://github.com/Crypho/cordova-plugin-secure-storage
Since the Android implementation of this secure storage uses the KeyStore, the users must have a secure screen-lock set (like fingerprint, pattern or PIN). The plugin provides functions to check this, so you will be able to give a warning (or block login) if this is not the case. Without a locked screen there is no way to save your keys in a secure way on Android.

How to protect Rest API key for Parse in html application

I have been learning with Angular.js and used Parse as the back-end service. To post data to the Parse RESTful API, you would pass REST API key and App ID in the header of the request like this:
var config = {headers: {"X-Parse-REST-API-Key":"someapikey", "X-Parse-Application-Id":"someappid"}};
$http.post("https://api.parse.com/1/classes/myobject", obj, config).success (
function(data) {console.log(data);}
);
While this is great for learning, I am wondering how would the RESTful API for Parse or any other Backend-as-Service vendor work in a real html application. The API key and application Id would be exposed in JavaScript and anyone smart enough to view source could modify data to your account.
The only way I can image this to work would involve a proxy server that adds to Api Key/App Id header. However, this would defeat the purpose of not having to run your own back-end server. Am I missing something here?
Here's what you're missing :)
The Parse.com REST/JavaScript keys are designed to be "out-in-the-wild." With these keys it's not possible to get around object access rules or beforeSave validations. Only the master key can do this. Protect the master key. A useful analogy is public-key encryption: you need share your public key but protect the private key.
Can anyone modify your data? Yes, but only if you let them. Can users query data belonging to other users? Yes, but again only if you let them. Parse has a few ways to ensure data integrity and security.
The first is per-object permissions. Use the Parse.com web interface to set a) whether or not classes can be created on the fly and b) CRUD permissions for existing classes. One of the easier steps to securing an app is to disable any class permissions not explicitly required. For example, objects created on the back-end which do not need to be writable (or perhaps readable) by end users.
The second is access control lists (ACLs). ACLs are set on each record. They specify which users or roles can read or write the record. Records without an ACL are public (any user can find it). If Sue creates a record that should be private to her, set an ACL as such. Tom won't be able to find it without the master key.
The third is Cloud Code. You're able to enforce mission critical business rules and data validations using beforeSave/afterSave functions. Determine what is truly important, and make sure it's validated against in these functions. It's also a good idea to set the ACL explicitly in these functions. ACLs can be passed in when creating the object, but it's possible for the end user to tamper with these.
Here is are summary rule of thumbs for security and integrity.
Object permissions should only be as open as necessary to support your requirements.
Every record should have an ACL, unless you're sure it shouldn't.
Most ACLs should be set with before/afterSave functions.
Any validations that must be enforced should checked for in before/afterSave functions.
Last thing: it's temping to think of all business logic as "important" and insist on "perfect integrity." This is overkill for many apps. Make sure you have enough server-side protection in place such that one user can never cause harm to you or to your other users. There is not much sense in worrying much beyond this (other than support costs). If someone is experimenting with your app but is prevented from intentionally or unintentionally interfering with others, maybe they'll find a whole new way to use it :).
Parse provides several access keys that can be used via different APIs:
Client key (for use from iOS and Android applications)
Javascript key
Windows key
REST key
Master key (to be used for REST API access, but not conforming to object ACL permissions)
When accessing Parse from client-side javascript, you should use the javascript API with the Javascript access key.
In terms of security, you will not be able to prevent users from using an access key that is used by client side javascript. Parse provides powerful access control via ACLs attached to each object, allowing you to restrict read/write access to each class to specified users. You can also prevent clients from creating new classes in the settings of your app. Take a look at the security guide here.

Categories

Resources