Wu Wei
Wu Wei

Reputation: 2277

Meteor: SSR necessary to secure admin part of application?

I have my extended user model in the Meteor.users collection, which I'm publishing most fields from to the client. Each user has an isAdmin field, set to false by default.

Now I have two concerns, which are linked:

  1. How to make sure, components meant for admins can only be rendered, if the isAdmin field in the Meteor.users collection is set to true?

  2. How to make sure, the isAdmin field on the Meteor.users collection cannot be modified from the clients console?


Concerning 1.

I'm hesitant to publish this field to the client and simply evaluate isAdmin on the client side.

I'm not sure if there is some hackish way through the console to simply change isAdmin in a way that would allow to render the component (or part of it) that is only meant for admins on the client. I could imagine that it is possible with Object.defineProperty() to do so, for example.

Should I use server-side rendering to secure the admin part of my UI?


Concerning 2.

Consider the first paragraph on Profile editing in this article about common mistakes. It suggests that isAdmin could easily be changed from the client by calling Meteor.users.update(Meteor.userId(), {$set: {'isAdmin': true}}) from the console.

When I run it, being logged in to my application, I get update failed: Access denied though.

But even the official documentation still suggests to add

// Deny all client-side updates on the Lists collection
Lists.deny({
  insert() { return true; },
  update() { return true; },
  remove() { return true; },
});

at https://guide.meteor.com/security.html#allow-deny

There is an answer, suggesting that it's enough to simply check for the isAdmin property on the server side, if you make sure that the Meteor.methods are server-only. But it doesn't talk about allow-deny at all and it's 6 years old.

Can anyone tell, what truly is the case as of today?

Upvotes: 1

Views: 61

Answers (1)

Jankapunkt
Jankapunkt

Reputation: 8413

Can anyone tell, what truly is the case as of today?

I would not put too much effort to secure the admin ui on the client. A router level redirect when isAdmin is false should be sufficient.*

Way more important here is to secure methods and publications because these are the parts where users can mess around with your application. For those it can't be secure enough:

  • use ValidatedMethod from mdg:validated-methods for Methods
  • write a factory function to create Publications similar to mdg:validated-method to allow basic checks in a mixin-style
  • both: check if the arguments are valid
  • both: check if the user exists
  • both: check if the user has sufficient roles -> I recomment alanning:roles as it makes permission level checks more secure as it checks for id-match existence in a dedicated collection rather than checking for a flag in the user collection (plus it decouples the users from the roles!)
  • Throw fast and a lot: throw on any suspicious inconsistency, try to cover any undefined state with throwing errors.
  • rate limit using ddp-rate-limiter every method and publication
  • write a simple sanity check on startup that ensures all methods and publications are rate-limited, you can get all registered methods/publications on the server at Meteor.startup via Meteor.server.method_handlers and Meteor.server.publish_handlers
  • write test a lot, especially for the admin related methods and try any weird and crazy input you can think of to see if it gets rejected or causes any weird behavior (which you want to avoid)

As far as I understood your question you have currently not integrated ssr and if you follow the above steps you can secure your admin-area of the application a lot without including ssr into your app (which itself can cause a lot of headache due to additional config etc.).

*if you decide to use the recommended alanning:roles package you would be better to also use it on the client to check the user's roles.

Upvotes: 2

Related Questions