The Dreamcode as described here: http://nobackend.org/dreamcode.html
That developers don't have to worry about the backend when developing web applications.
Is very interesting. However I have few question on building application logic in the front-end.
The question is, even with authentication being processed in the backend.
What are the ways to make the app logic obfuscated and not to be copied easily?
For the application models it is easy for a server to receive it. However looking with the Store and Public Store idea from Dreamcode, how can we handle fields that are not meant to be sent back to the front-end for security purposes?
For example in this Gist it show how to get object by id:
// find one object
var type = 'note';
var id = 'abc4567';
store.find(type, id)
.done(function (object) {});
The issue here is, for example I have an application that guest user can post a document and edit it later with a password. A guest user saves a document with a encrypted password in it.
When other users "views" the document from the front-end application. The Dreamcode data store will return all the fields for this document object (based on the Dreamcode specification) including the encrypted password, which is not good.
So how can we deal with making a Front-end application with Dreamcode with these potential limitations?
Related
I'm good with registering users, login, etc.
Now I'm getting into modifying users with:
this.backand.object.update('users', user.userId, user)
but I can see that only my table gets modified, while I'll also need to modify the "Registered Users" table existing in "Security & Auth > Registered Users".
I understand I might need to create a custom action...maybe "Before Update"? ...but I can't find documentation on how to modify that specific table (via API or via BackAnd actions).
Thank you.
thanks for using Backand! We don't offer any methods via the SDK to update the registered users. You can use the HTTP object to send a call to the back-end's REST API directly, hitting the same URL that the SDK requests when creating a new user, but this isn't officially documented. In general, we try to limit direct modifications of the registered users table, as there are some security concerns regarding how frequently the data is accessed and modified, but you can access the users object directly via the /users URL. There is an article in our documentation at http://docs.backand.com/en/latest/apidocs/security/index.html#link-your-app-39-s-users-with-backand-39-s-registered-users that covers an automated process for making these kinds of changes - you should be able to adapt some of the server side code in that example to work with your use case.
One alternative that would work now would be to have any change in basic information (username, password, firstname, lastname) result in a new user being created, and you could then use a custom action to perform the migration to the new user, but that is unnecessarily complex. I will add a ticket for our developers to look at adding this registered user management functionality in the future.
I’m trying out the Authentication component in Firebase.
A) I have a situation where the web client javascript code firebase-app.js and firebase-auth.js 3.3.0...
firebase.auth().onAuthStateChanged and
firebase.auth().currentUser
... return different expected logged in user values, than the jvm
client [com.firebase/firebase-client-jvm "2.5.2"]. The JVM client
returns null user data.
My JVM client code is taken from Firebase’s QuickStart Guide. In
the JVM client, neither onAuthStateChanged handler is called, nor
does firebaseObj.getAuth() return any data.
I’m wondering where the discrepancy is. The web client was initialized
with “codepairio.firebaseapp.com”.
var config = { ... authDomain: “<my-firebase-app>.firebaseapp.com"
};
firebase.initializeApp(config);
B) The java client was initialized with “https://.firebaseio.com”. I’m using this URL as it’s specified in the guide and mentioned here. Also, if you try
to use “.firebaseapp.com”, you’ll get an error:
“IllegalStateException For a custom firebase host you must first set your authentication server before using authentication features!”.
So with that out of the way, we have...
new Firebase("https://<my-firebase-app>.firebaseio.com”);
Any ideas on how to get them to observe the same source of truth?
====> [EDIT]
Ok, I've gotten a bit further. It turns out that I was using an older firebase API (A) than the latest (B).
A) https://www.firebase.com/docs/android/guide/user-auth.html
B) https://firebase.google.com/docs/auth/server/
So if we look at Firebase's documentation for how to handle user's, we see this:
A Firebase User object represents the account of a user who has signed
up to an app in your Firebase project. Apps usually have many
registered users, and every app in a Firebase project shares a user
database.
A Firebase User instance is independent from a Firebase Auth instance. This means that you can have several references to different
users within the same context and still call any of their methods.
But i) the notion of FirebaseAuth.getInstance().getCurrentUser() doesn't make sense if our app is dealing with multiple users. And further, the FirebaseAuth.getInstance().getCurrentUser() method doesn't even exist. The FirebaseAuth class file (in com.firebase/firebase-client-jvm "2.5.2"), doesn't reflect the documentation.
$ javap -classpath ~/.m2/repository/com/google/firebase/firebase-server-sdk/3.0.1/firebase-server-sdk-3.0.1.jar com.google.firebase.auth.FirebaseAuth
Compiled from "FirebaseAuth.java"
public class com.google.firebase.auth.FirebaseAuth {
public static com.google.firebase.auth.FirebaseAuth getInstance();
public static synchronized com.google.firebase.auth.FirebaseAuth getInstance(com.google.firebase.FirebaseApp);
public java.lang.String createCustomToken(java.lang.String);
public java.lang.String createCustomToken(java.lang.String, java.util.Map<java.lang.String, java.lang.Object>);
public com.google.firebase.tasks.Task<com.google.firebase.auth.FirebaseToken> verifyIdToken(java.lang.String);
static com.google.api.client.json.JsonFactory access$000();
static com.google.firebase.auth.internal.FirebaseTokenVerifier access$100(com.google.firebase.auth.FirebaseAuth);
static {};
}
C) So far, using Firebase's Authentication service, on the server is very opaque to me at the moment. Can someone clarify the semantics of handling multiple users, getting lists of logged in users, verifying users with request tokens, etc. Where's the working API for all this?
I actually got an answer back, from Firebase Support, on this. Turns out that, based on the documentation, the capabilities available for the server side (nodejs and java) in terms of authentication are only i) creating custom tokens and ii) verifying ID tokens. As of now, handling users or getting the current user is not supported yet.
For the creation and verifying tokens in the server side, you can refer to this guide for more information. You can also check these posts for more information.
Firebase Java client with custom authentication
Is it still possible to do server side verification of tokens in Firebase 3?
https://firebase.googleblog.com/2013/03/where-does-firebase-fit-in-your-app.html
Hth
I'm building an app and would like some feedback on my approach to building the data sync process and API that supports it. For context, these are the guiding principles for my app/API:
Free: I do not want to charge people at all to use the app/API.
Open source: the source code for both the app and API are available to the public to use as they wish.
Decentralised: the API service that supports the app can be run by anyone on any server, and made available for use to users of the app.
Anonymous: the user should not have to sign up for the service, or submit any personal identifying information that will be stored alongside their data.
Secure: the user's data should be encrypted before being sent to the server, anyone with access to the server should have no ability to read the user's data.
I will implement an instance of the API on a public server which will be selected in the app by default. That way initial users of the app can sync their data straight away without needing to find or set up an instance of the API service. Over time, if the app is popular then users will hopefully set up other instances of the API service either for themselves or to make available to other users of the app should they wish to use a different instance (or if the primary instance runs out of space, goes down, etc). They may even access the API in their own apps. Essentially, I want them to be able to have the choice to be self sufficient and not have to necessarily rely on other's providing an instance on the service for them, for reasons of privacy, resilience, cost-saving, etc. Note: the data in question is not sensitive (i.e. financial, etc), but it is personal.
The user's sync journey works like this:
User downloads the app, and creates their data in the process of using the app.
When the user is ready to initially sync, they enter a "password" in the password field, which is used to create a complex key with which to encrypt their data. Their password is stored locally in plain text but is never sent to the server.
User clicks the "Sync" button, their data is encrypted (using their password) and sent to the specified (or default) API instance and responds by giving them a unique ID which is saved by the app.
For future syncs, their data is encrypted locally using their saved password before being sent to the API along with their unique ID which updates their synced data on the server.
When retrieving synced data, their unique ID is sent to the API which responds with their encrypted data. Their locally stored password is then used to decrypt the data for use by the app.
I've implemented the app in javascript, and the API in Node.js (restify) with MongoDB as a backend, so in practice a sync requests to the server looks like this:
1. Initial sync
POST /api/data
Post body:
{
"data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd..."
}
Response:
{
"id":"507f191e810c19729de860ea",
"lastUpdated":"2016-07-06T12:43:16.866Z"
}
2. Get sync data
GET /api/data/507f191e810c19729de860ea
Response:
{
"data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd...",
"lastUpdated":"2016-07-06T12:43:16.866Z"
}
3. Update synced data
POST /api/data/507f191e810c19729de860ea
Post body:
{
"data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd..."
}
Response:
{
"lastUpdated":"2016-07-06T13:21:23.837Z"
}
Their data in MongoDB will look like this:
{
"id":"507f191e810c19729de860ea",
"data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd...",
"lastUpdated":"2016-07-06T13:21:23.837Z"
}
Encryption is currently implemented using CryptoJS's AES implementation. As the app provides the user's password as a passphrase to the AES "encrypt" function, it generates a 256-bit key which which to encrypt the user's data, before being sent to the API.
That about sums up the sync process, it's fairly simple but obviously it needs to be secure and reliable. My concerns are:
As the MongoDB ObjectID is fairly easy to guess, it is possible that a malicious user could request someone else's data (as per step 2. Get sync data) by guessing their ID. However, if they are successful they will only retrieve encrypted data and will not have the key with which to decrypt it. The same applies for anyone who has access to the database on the server.
Given the above, is the CryptoJS AES implementation secure enough so that in the real possibility that a user's encrypted data is retrieved by a malicious user, they will not realistically be able to decrypt the data?
Since the API is open to anyone and doesn't audit or check the submitted data, anyone could potentially submit any data they wish to be stored in the service, for example:
Post body:
{
"data":"This is my anyold data..."
}
Is there anything practical I can do to guard against this whilst adhering to the guiding principles above?
General abuse of the service such as users spamming initial syncs (step 1 above) over and over to fill up the space on the server; or some user's using disproportionately large amounts of server space. I've implemented some features to guard against this, such as logging IPs for initial syncs for one day (not kept any longer than that) in order to limit a single IP to a set number of initial syncs per day. Also I'm limiting the post body size for syncs. These options are configurable in the API however, so if a user doesn't like these limitations on a public API instance, they can host their own instance and tweak the settings to their liking.
So that's it, I would appreciate anyone who has any thoughts or feedback regarding this approach given my guiding principles. I couldn't find any examples where other apps have attempted a similar approach, so if anyone knows of any and can link to them I'd be grateful.
I can't really comment on whether specific AES algorithms/keys are secure or not, but assuming they are (and the keys are generated properly), it should not be a problem if other users can access the encrypted data.
You can maybe protect against abuse, without requiring other accounts, by using captchas or similar guards against automatic usage. If you require a catcha on new accounts, and set limits to all accounts on data volume and call frequency, you should be ok.
To guard against accidental clear-text data, you might generate a secondary key for each account, and then check on the server with the public secondary key whether the messages can be decrypted. Something like this:
data = secondary_key(user_private_key(cleartext))
This way the data will always be encrypted, and in worst case the server will be able to read it, but others wouldn't.
A few comments to your API :) If you're already using HTTP and POST, you don't really need an id. The POST usually returns a URI that points to the created data. You can then GET that URI, or PUT it to change:
POST /api/data
{"data": "..."}
Response:
Location: /api/data/12345
{"data": "...", "lastmodified": "..." }
To change it:
PUT /api/data/12345
{"data": "..."}
You don't have to do it this way, but it might be easier to implement on the client side, and maybe even help with caching and cache invalidation.
I have created a chat message functionality. The message stores the userid of sender and receiver. How can I get other details of the user just based on the userid?
Is creating a Meteor method the best way or I have to create publish/subscribe pattern for it.
I want to avoid sending all users data to client side.
I tried creating a meteor method but I don't think its the best approach.
Meteor.methods({
getUserInfoById: function (usrId) {
//console.log("BEGIN");
//console.log(usrId);
var user = Meteor.users.findOne(usrId);
//console.log(user);
//console.log("END");
return user;
}
});
Create a publisher (and also a subscriber) for the data about other users that you want a given user to see. You can restrict the fields returned using the {fields: ...} qualifier in the query.
This is a very common pattern. Using a method for this is an anti-pattern due to the extra round-trip delay for something you're likely to show quite often, i.e. another user's username or avatar.
Let's say I want to create a ToDo list using angular. I have a REST API that stores the items in db and provides basic operations. Now when I want to connect my angular app to the REST api I found two ways to do so following some tutorials online:
1.Data gets handled in backend only: A service gets created that has a getAllTodos function. This function gets directly attached to scope (e.g. to use it in ng-repeat):
var getAllTodos = function() {
//Todo: Cache http request
return $http...;
}
var addTodo = function(todo) {
//Todo: Clear cache of getAllTodos
$http...
}
2.Data gets handled in frontend too. There is a init function that initializes the todo variable in the service.
var todos = [];
var init = function() {
$http...
todos = //result of $http;
};
var getAllTodos = function() {
return todos;
};
var addTodo = function(todo) {
$http...
todos.push(todo);
}
I've seen both ways in several tutorials but I'm wondering what would be the best way? The first one is used in many tutorials where the author from the start has in mind to attach it to a REST API. The second one is often used when the author at first wants to create the functionality in the frontend and later wants to store data permanently using a backend.
Both ways have its advantages and disadvantages. The first one reduces code duplication in frontend and backend, the second one allows faster operations because it can be handled frontend first and the backend can be informed about changed afterwards.
//EDIT: Frontend is Angular.JS Client for me, backend the REST API on the server.
Separation of Frontend and Backend is often done for security reasons. You can locate Backend on a separate machine and then restrict access to that machine to only calls originating from the Frontend. The theory is that if the Frontend is compromised, the Backend has a lower risk factor. In reality if someone has compromised any machine on your network then the entire network is at risk on one level or another.
Another reason for a Backend/Frontend separation would be to provide database access through the Backend to multiple frontend clients. You have a single Backend with access to the DB and either multiple copies of the Frontend or different Frontends that access the Backend.
Your final design needs to take into account the possible security risks and also deployment and versioning. With the multiple-tier approach you can deploy individual Frontends without having to drop the Backend, and you can also "relocate" parts of the application without downtime. The more flexible the design of your application, the deployment may be more complicated. The needs of your application will depend on if you are writing a simple Blog or a large Enterprise application.
You need frontend and backend functionality. In frontend you preprape data which are being send and in the backend you make request to server.