Querying Non-existent MongoDB Fields


#1

Hey all,

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.

This subtly different from how I expect most people envision this functionality working. Read more about it in the full article.


#2

How would malicious user pass his own object into query?
I mean… if he can pass any object, he could just pass {} and still get all the documents.

Correct me if I’m wrong, I’m kinda ill.


#3

There wouldn’t be any query injection going on here.

The example I used in the article looks like this:

Meteor.publish("documents", function() {
  return Documents.find({ 
    $or: [
      { userId: this.userId },
      { sharedWith: this.userId }
    ]
  });
});

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".


#4

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.

Also check the advices: https://guide.meteor.com/methods.html#validated-method to validate your parameters.