The actionLinkHandler
method was found to allow Message ID Enumeration with Regex MongoDB queries.
The Meteor method actionLinkHandler calls an actionLinks wrapper getMessage
to find affected messages:
Meteor.methods({
actionLinkHandler(name, messageId) {
if (!Meteor.userId()) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'actionLinkHandler' });
}
const message = actionLinks.getMessage(name, messageId);
const actionLink = message.actionLinks[name];
actionLinks.actions[actionLink.method_id](message, actionLink.params);
},
});
The actionLinks.getMessage method does not validate the input data, so that a { $regex: ".*" }
pattern can be used to enumerate for the existence of Messages with MongoDB Injection.
getMessage(name, messageId) {
const userId = Meteor.userId();
if (!userId) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { function: 'actionLinks.getMessage' });
}
const message = Messages.findOne({ _id: messageId });
if (!message) {
throw new Meteor.Error('error-invalid-message', 'Invalid message', { function: 'actionLinks.getMessage' });
}
// ...
}
Whenever a Message ID does not match any existing message, the server will respond with invalid-message
error. When it does exist, a different response (or error) is returned, so that the guess can be evaluated.
Meteor.call(
"actionLinkHandler",
"joinJitsiCall",
{ $regex: ".*" },
console.log
);
Although only Message IDs (and not their content) can be enumerated, mitigating this issue becomes relevant to prevent adversaries from stacking it with other information disclosure vulnerabilities that would leak a message content for known Message IDs.
messageId
for String typeAuthenticated adversaries can enumerate the server for existing Message IDs.
Fixed in 4.7.5, 4.8.2 and 5.0>