Meteor allow/deny vulnerability disclosure

All Meteor developers should be aware of this recently discovered security vulnerability. Please read this disclosure for full details.

The vulnerability has already been fixed in Meteor and developers should see the Resolution section below for a meteor update command which patches existing applications.

In short, we recommend all developers update and deploy, however applications using the attachSchema method from aldeed:collection2 (or a similar method from another package) on the same collection where allow or deny rules are in place should pay particular attention.

Description

An exploitable security vulnerability has been discovered in Meteor through a downstream project’s bug bounty program which affects a commonly used application configuration, and could be used to access users’ private data or circumvent other protections an application may have in place.

By sending a specially crafted WebSocket payload, a malicious client can execute an update operation on individual MongoDB documents in violation of the collection’s allow and deny rules, when particular third-party packages are installed. When the malicious WebSocket frame is evaluated against the developer-configured rules, the exploit disables specific rules which would have blocked the operation, thus allowing the operation to be executed.

Impact

While a default Meteor configuration using Meteor’s core packages (for example, the accounts-* packages and allow-deny) is not automatically vulnerable, the exploit becomes possible when certain commonly-used third-party packages are also installed.

An application may be affected if it utilizes a MongoDB collection’s Mongo.Collection#allow or Mongo.Collection#deny methods to define collection-level rules and also uses any third-party packages to enforce a schema on the same collection. This consideration applies whether the application uses <CollectionName>.allow({...}) or <CollectionName>.deny({...}) directly, or the third-party packages manage the collection’s allow or deny rules on its behalf. Furthermore, Meteor.Collection is a (deprecated) alias for Mongo.Collection and is therefore subject to identical considerations.

Only Mongo update operations for documents which a user was allowed to update are affected. In the case where an update is allowed, this exploit may permit updates to unexpected parts of that document. This nuance becomes particularly relevant if an application has top-level properties which dictate a user’s permission level, such as an isAdmin (or similar) field.

Other protected operations such as insert, remove, or fetch are not affected.

If an application does not use any Mongo.Collection#allow methods directly or indirectly, we have no evidence of exploitability. Additionally, if a collection explicitly denies all updates with <CollectionName>.deny, then it will not be vulnerable.

If an application includes one of the following third-party packages, combined with allow rules without explicit deny rules (as outlined above), it may become vulnerable. The packages themselves are not to blame, though their presence may enable the exploit. These particular packages were chosen according to their popularity, not for any special role or fault in the exploit. Other packages which provide similar functionality should also be regarded with caution:

  • aldeed:collection2 or aldeed:collection2-core or any other package which may be used for schema validation and enforcement.
    • While these packages are functioning as designed, in some configurations they remove certain update parameters, which can change the behavior of the update. A collection which has not had a schema attached to it (for example, using <CollectionName>.attachSchema) should not be vulnerable.
  • ongoworks:security
    • Versions of this package after 2.0 no longer create allow and deny rules automatically, which means the exploit should not work, though appending allowInClientCode() to a normal permission chain may result in the addition of vulnerable allow and deny rules.
  • alanning:roles
    • This package stores permission information as a top-level roles property on the user document, which, if exploited properly, could be modified.

Resolution

The vulnerability has been fixed with the release of version 1.0.9 of the allow-deny Meteor package.

Regardless of whether you believe your application is affected, we highly recommend any application update to allow-deny@1.0.9.

After updating and deploying the fix, applications which match the criteria for being affected should audit sensitive Mongo documents to ensure no user permissions have been maliciously elevated and no sensitive fields have been modified.

Meteor 1.4 or later

The command to update the allow-deny package and patch the vulnerability is:

meteor update allow-deny

After running this command, please verify that allow-deny@1.0.9 was installed, either by examining the output of the command or looking at your .meteor/versions file.

Prior to Meteor 1.4

Any application running less than Meteor 1.4 should update to at least Meteor 1.4.x and apply this update using the above instructions. Meteor versions prior to 1.4 utilize Node.js 0.10.x, which is no longer receiving security updates from the Node Foundation and might already be susceptible to security vulnerabilities unrelated to this disclosure.

Running an unmaintained Node.js version is not recommended!

Credit

Meteor fully believes in ethical disclosure of vulnerabilities by security researchers who notify us with details and provide us time to address and fix the issues before public disclosure.

Credit for the discovery of this vulnerability goes to Sam Sun who reported the bug in Meteor as part of the LegalRobot bug bounty program they operate through HackerOne.

Please contact security@meteor.com if you wish to report a vulnerability in Meteor.


We’ll be actively monitoring this thread. Please keep your responses on-topic and helpful.

20 Likes

Do you have any more detail about the specific issue and how it was fixed? 6e42505 looks like the most recent commit to allow-deny, but that looks like a simple change to avoid Array.prototype.includes that shouldn’t have any security implications. My company doesn’t use any third party packages for our collection ACL management, but we do have a number of Mongo.Collection#allow and Mongo.Collection#deny calls as well as a fairly complex package hierarchy, and we’d just like to know what the underlying issue was to confirm that we’re unaffected. Thanks!

1 Like

Allow/deny reminder

Most developers have moved on from the allow and deny pattern, but as a reminder, Meteor has discouraged the use of allow and deny rules for some time due to the ease of misconfiguring them, usually due to unintended oversight. (See some interesting details in this thread!) While in this case, they actually malfunctioned under certain conditions, it’s worth emphasizing that we still discourage their use. The use of Meteor methods with specific, well-defined purposes which handle the updates themselves is a better approach.

1 Like

Updating allow-deny to 1.0.9 will ensure the vulnerability is fixed, no matter what configuration you have.

In order to reduce the chance of exploitation by a malicious user taking advantage of (potentially) vulnerable applications which haven’t been updated, we won’t be publicly highlighting what the exploit was at this time.

Ultimately, the disclosure above emphasizes the scenario where an application should be considered affected, but I’ll re-highlight this section:

applications using the attachSchema method from aldeed:collection2 (or a similar method from another package) on the same collection where allow or deny rules are in place should pay particular attention.

If this matches the configuration of your application, you should consider yourself potentially affected and react accordingly. Contrarily, if an application and its packages don’t have schema enforcement in place on the same collection which uses allow and deny rules, we have no evidence to support the exploit.

The Meteor.users collection does use an allow rule to limit updates to the profile of the current user so if you enforce a schema on your users collection, we’d suggest auditing the users collection to see if a user could have gained elevated privileges.

3 Likes

I have read your announcement and I want to protect my project. Could you tell me how to transform this code (from the guide) to make it more secure :

export const updateText = new ValidatedMethod({
name: ‘todos.updateText’,
validate: new SimpleSchema({
todoId: { type: String },
newText: { type: String }
}).validator(),
run({ todoId, newText }) {
const todo = Todos.findOne(todoId);
if (!todo.editableBy(this.userId)) {
throw new Meteor.Error(‘todos.updateText.unauthorized’,
‘Cannot edit todos in a private list that is not yours’);
}
Todos.update(todoId, {
$set: { text: newText }
});
}
});

Thanks!

Yep, totally understood. We don’t think that description matches our application, but we’ll immediately update allow-deny to 1.0.9 as a precaution. Thanks!

Marcus

1 Like

@mklftn If you don’t use allow or deny rules on your Todos collection (which you would have done with Todos.allow({...}) or Todos.deny({...}), you would not be affected by this vulnerability.

Regardless, you can leave your code exactly how it is and protect yourself by updating the allow-deny package, as explained above, with:

meteor update allow-deny

Can we assume meteor update, meteor update --all-packages and meteor update --packages-only would include the fix?

We provided one simple command to make it easy to apply the update to the affected package.

Though, yes, each of those three commands (which each do different things) should get the update in their own ways. Of course, updating all packages, including third-party packages (which the latter two commands will do) could introduce update problems due to changes in those packages, which is again why we suggested the one simple command for simplicity.

An application using alanning:roles but without any other explicit allow rules should be considered vulnerable and in need of update or the bug is only triggered when there are additional rules?

If the application does not also use “any third-party packages to enforce a schema on the same collection” (quote from above), then it should be fine.

But really, all applications should apply the update to allow-deny just to be sure. The update is simple and compatible with every Meteor 1.4+ application.

So, if you haven’t ever used allow/deny in meteor applications you’re good to go, right?

Warning for anybody moving to 1.5.2.1:

This affected our app severely, so we had to move back to 1.5.2 and manually pin the allow-deny package to 1.0.9

Also manually apply this fix by forking minimongo (also has serverside implications):

The last issue can also have severe issues, because documents that should not be returned, might be returned anyway. In our case the $elemMatch was used for autorisation purposes, meaning users could see documents that they did not have access to. That last sentence could use an exclamation mark. Or 2.

So anyway, be careful with the upgrade and stick to pinning the allow-deny version for now.

Please upgrade your allow-deny package regardless:

meteor update allow-deny

Ok, since 1.5.2.1 is causing problems for some and I’d rather this thread focus on upgrading allow-deny and avoid going down the road of warnings and a bit too much confusion so I’ve removed any announcements in this thread (which were my own) of using 1.5.2.1 or 1.4.4.4 as a proxy to receive the allow-deny update and instead just left it with the instruction in the original post to only update allow-deny.

Let’s discuss the specific issues you’re having in the relevant GitHub issues which you’ve linked.

1 Like

Hello ,

Two Questions …
I am using Meteor Methods on the Client side
But For more Security I am using the Allow/Deny Only on server side
1- Am I Safe ?
2 -And does the Allow/Deny@1.0.9 secure the application regardless of what other packages I am using ?

Regards

allow and deny only have any effect on the server.

If you update allow-deny to 1.0.9 and you have perfectly written allow-deny rules, probably. But the general rule is to not use allow and deny rules. This has been the suggestion in the Meteor guide for a while.

It fixes the vulnerability. I cannot speak for the security of your existing allow and deny rules, which could have already had mistakes due to the complexity of writing them. (see previous paragraph) :slightly_smiling_face:

Ultimately, developers should be using Meteor methods.