Last week I had someone ask me about a vulnerability in their Meteor application. It turns out the vulnerability was cased by an often overlooked “feature” of MongoDB.
A query like this:
Docs.find({
nonExistentField: undefined
});
Will return all Docs who either nonExistentField set to null, or who don’t have a value set to nonExistentField at all.
I’ve seen lots of people rely on this kind of userId filtering to restrict publications to return only documents owned by the current user. Unfortunately, this doesn’t work on other fields that may not always have values.
In this case, sharedWith will be unset for unshared Documents, and will all be returned when an unauthenticated user subscribes to "documents".
Put a check for not logged in users, or users which don’t have the right role (like admin) just in the function.
There are 2 things you want to check:
should this publication be accessed at all?
which data should I return?
If the first one fails return and stop. That keeps security checks simple and testable. Like you do in your article. Whether you should return an exception is debatable. Some times it might be better to return []; or this.ready(); depending on how you subscribe.
An $or statement is a tricky one, totally agree that needs attention. Testing is is also hard because there are more variations which are possible than most people expect at first sight.