Concept of a SaaS system - javascript

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

Related

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.

Authenticating with PKI in Angular

I'm wrestling with trying to authenticate in an AngularJS application using PKI. All of the questions and examples I've seen show authentication using a login/password instead. However, I am running on an intranet, where we use PKI keys consistently. I've read the various suggestions online, but none seem to discuss my particular architecture.
The Angular side contains multiple pages/controllers, and I have no way of controlling which page the user visits first. I need the authorization information on each page.
The application is set up with a NodeJS REST service to get the user's authorizations and other information based on the user's public key (passed in thru the certs). Since the NodeJS service must contact external servers, I want to only invoke it only once, and retain an authorizedUser object (probably in rootScope?)
I've looked at creating services, providers, etc. But none seem to fit this challenge. To summarize:
Authorization using PKI certs, not login/password
Certs used to reach NodeJS REST service, but must only be invoked once
Multiple Angular controllers/pages need authorization information
What would be the best approach here?
OK - I figured it out. My approach was to put the webservice call to the NodeJS backend in the module.run(), and set the $rootScope within the $http.get().success() block. The NodeJS backend gets the certs from the webservice call, and does the lookups it needs to do.
I'm not sure if that's the best approach, but it works for now.

Restrict the registration for a machine C#

I have a web application that has form based authentication.
the application has registration functionality also. Since last few weeks, i have observed that some users with specific domain is making fake entries into the website and getting the benefits as We do not have any approval workflow.
this user either do it manually or run some script. We thought that we can restrict the registration process as per IP based, however this is not possible to get the visitor exact IP address using C# (please correct if i am wrong).
Can we do it using some other techniques. our requirement is - single registration from a machine per 2 days.
unfortunately I would call this mission impossible.
Idea 1: IP address. The user can use a proxy to register multiple accounts depending on how many proxy he can find (there are a bunch on the internet for free)
OR they could just fake the ip package by putting a random ip in the header. Since all they need is to register so it doesn't matter if the confirmation message was sent to another random guy
Idea 2: one registration per machine. I could fake as many machines as I want with virtual machine and you will have no way to tell from http request.
Alternatively I could just fake all the information with raw http request and I can do that with a script with no issue.
And from what I know you don't have the system right to read hardware id from js (correct me if im wrong)
No method is guarantee to restrict 2 registration per day but IP based method should work against most normal users. Do keep in mind that everyone using the same router could have the same IP (example school, public wifi in apartment)
You could find out the user's IP address within HttpContext object
Whatever your restriction would be - it will be based on the data the browser sends (as long you restrict a specific computer).
Your main desire is to create a "footprint" on that machine in order to use it later - per request.
Whatever your manipulation would be, you should also obfuscate your JS code.
for example, on pageload code you can request for httpheaders dedicated to that machine and save them in cache, then you generate a guid for the client which it suppose to use in order to register.
another option is to use AES to encrypt the data before sending it "on the wire", that way you won't be able to manipulate it.
the most important thing is that once you "drop" a js code on the client he can do whatever he wants, the question is how hard it would be.
**edit:
a more secured way but more complicated that i have once used is creating a sync-key.
an async ajax call to the server requesting an encryption key.
the server call will save the new guid-key in memory and will generate a new one for each request.
you can use this idea to keep track of user debug and browser behavior.
as debuging will hold the code from running the sync key will be change and you can "catch" him.
Neither cookies nor IP can protect against fake entries.
You should look at it from another side. You get unwanted entries and you don't know if it's an automated bot, or spammer, or someone who just doesn't care about your data. Instead of banning entries you should think how to validate them. For example, if you get "aaaaa" as a name and "bbbbb" as an email address - add, at least, regexp validation on client and server side to ensure you get data in a required format. Next level would be to verify the email address by querying the mail server or sending validation email. This will not only help to stop spammers, but also people who doesn't care. If you think it's an automated bot - add a captcha. In case of emergency - ban IP in the web.config (See ASP.Net How to limit access to a particular IP address to a particular page through web.config file (.htaccess similar)?)

CouchDB and Cloudant Security

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.

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