What logic do you consider safe on the client side?

So one of the features of Meteor is the ease in which you can run code on both the client and server side.

However, you can still put logic in the server directory if you don’t want it exposed to the client.

I would like to hear experiences from a security point of view about what logic you keep solely on the server side?

The reason I ask is I’m trying to decide whether my access rules to be server only. So I have a file called “AccessRules.js” and it just contains a host of functions such as “CanEditDocument(docId)” which will contain the business rules about when a user can edit a particular document.

Right now, this file sits on the server folder and I use meteor methods to access this file from the client. So I might have to go Meteor.call(‘CheckCanEditDocument’, docId) from the client side to see whether I can edit the document.

But Meteor methods work asynchronously. This is a problem when I’m trying to use this logic in handlebar helpers. So say, I have a button that I only want to display if I can edit the document.

{{#if canEditDocument }}
 <button>Edit</button>
	
{{/if}}

My helper function below is not going to work because the Meteor call doesn’t return the result, the callback does.

canEditDocument: function(){
	return Meteor.call("CheckCanEditDocument", docId);

}

So this means that whenever I load up a template I have to do all the Meteor.call access rule checks, and save them in session variables and then my canEditDocument helper reads from the Session variables. That just sounds really convoluted to me.

So I am questioning, are access rules safe on the client side? Is it dangerous if the user knows the conditions for which a document can be editted or any of these other business rules?

What have you guys generally put in the server only code? And do you put it in there because of security concerns or its code that only works on the server side.

Hi, I use this package : https://atmospherejs.com/dburles/collection-helpers
Read more : http://joshowens.me/fat-models-skinny-templates/
Example :smile:

Documents = new Meteor.Collection('documents');

Documents.helpers({
   canEditDocument : function(){
      var currentUserId = Meteor.userId() || '';
      return Roles.userIsInRole(currentUserId, ['admin','moderator']) || (currentUserId == this.createdBy);
   }
})

Template.document

<template name="document">
    {{#with document}}
        <h1>{{title}}</h1>
        <p>{{body}}</p>
        {{#if canEditDocument }}
            <button>Edit</button>
        {{/if}}
    {{/with}}
</template>
1 Like

Have a look at this SO thread http://stackoverflow.com/questions/27330321/meteor-method-vs-deny-allow-rules

I don’t think that’s really related.

Firstly, I have deny= true for all my collections. I just don’t believe in having one single method where I have to put in all my validations and / or business rules for how my collections can be inserted, updated and deleted. I’m much more comfortable having a single entry points for each scenario I want to change data on the server.

But regardless, allow and deny rules are about writing data to the server database. I’m not writing any data, i’m reading data. My question is about what business rules logic is appropriate to be in a place where the client can read.

1°) For the data that your user is not allowed to read, don’t send it ! This is managed through publications based on user id.
2°) For the data that your user is not allowed to modify, block him at database level ! This is managed through permissions.
3°) If you can, avoid methods. If you use methods, check for user id, and check every arguments.
With these rules, you are avoiding most of malicious usage of the data.

Now about your “business rules” question.
If your user is not malicious, business rules on client are OK.
If your user is malicious, business rules on client are still OK. But send him only the data he is allowed to mess with, enforced by rules 1, 2 and 3.

Example : let’s pretend you are coding a bank account application (probably not the best match for Meteor, but let’s talk about an extreme case).
If you want your application to show the client the sum of all his accounts, it’s probably ok to implement the suming function on the client.
Your client has the right to see the amounts on every one of his account, so the publication allow that.
But the client has no right to modify the accounts value directly, so the permissions don’t allow that.
A malicious user could mess up with the sum function and pretend for himself that he has a billion dollar on his savings account, but that won’t have consequences on your applications and its data.
Now let say that you want to implement money transfer between your client accounts or between one of your client account and a foreign one, the read only nature (permissions) of the data makes it impossible in the first case (own accounts), and the non availability of the foreign data (publications) makes it impossible in the second case, so the natural place for these business rules is on the server.

1 Like

From a data point of view, definitely not concerned. Just make sure your publication exposes the right data like you said. I also have deny permissions for everything - the only way you can create or edit data on the server is via Meteor methods. This might not be the “Meteor” way, but having defined endpoints makes it easier to manage a proper workflow.

This post really is about the business rules - I’m concerned that if you’re giving the user knowledge about how the server side works, including the structure of your data, permissions etc. maybe potentially this could be used to find exploits? I don’t know how big of a concern this is - but in a traditional app, most users see hardly any of the server side code.