Mongo find with userid returns all docs if there is no userId - security hole


#1

I have the following in my publish.js file I’m trying to return all the topics that belong to that user (current logged in user)

Meteor.publish('topics' , function() {
        return Topics.find({$or:[{userId: this.userId},{collaboratorsIds: this.userId},{inviteeId:this.userId}]});
}); 

This works great however there is a security hole, if the user is not logged all the topics are published I tried the following which fixes but now my app hangs on the sub waiting for publish to return something

Meteor.publish('topics' , function() {
    if(this.userId)
        return Topics.find({$or:[{userId: this.userId},{collaboratorsIds: this.userId},{inviteeId:this.userId}]});
});

I tried adding this.ready or return []; but that does nothing what’s the correct approach


#2

I believe it’s an issue with the $or, it checks and if there is no user id it falls back to Topics.find();


#3

When userId is undefined, the query Topics.find({$or:[{userId: this.userId},{collaboratorsIds: this.userId},{inviteeId:this.userId}]}) will return any topic where userId is undefined or collaboratorsIds is undefined or inviteeId is undefined. Because undefined also means “non-existent”, depending on your case, the result might be all documents.

I think the code you’re looking for is:

Meteor.publish('topics' , function() {
    if(this.userId)
        return Topics.find({$or:[{userId: this.userId},{collaboratorsIds: this.userId},{inviteeId:this.userId}]});
    this.ready();
});