Basic Auth For Hiding Your Application

Written by Pete Corey on Jul 6, 2015.

The package-based Basic Auth solution presented in this post leaves DDP endpoints exposed to unauthorized users. For more information, read my follow-up post on Bypassing Package-Based Basic Auth.

Recently I’ve been playing with techniques for sharing private Meteor applications with others. An example of this may be showing a beta version of an application to a client. That client may not want any of the application exposed to the public, including splash pages or login screens.

I’ve found that a quick solution to this problem is to use good old basic authentication.

Adding basic auth to a Meteor application is incredibly simple thanks to a handful of packages that have wrapped the basic-auth-connect npm package. I’ve whipped up a quick example using kit:basic-auth and deployed it to Use username/password for your login credentials.

Adding this basic level of protection was as simple as adding the package to my project:

meteor add kit:basic-auth

And updating my settings.json file with the credentials:

    "basicAuth": {
        "username": "username",
        "password": "password"

Basic authentication isn’t seen much anymore, and it’s not a particularly useful security paradigm, especially for Meteor applictations. However, it can be incredibly useful when trying to quickly lock down a web asset, or in our case, a single-page web application.

Black Box Meteor - Shared Validators

Written by Pete Corey on Jun 29, 2015.

Discover Meteor’s recent blog series about allow and deny security has done a great job at raising awareness around the security concerns that surround collection validators. Check out their Allow & Deny: A Security Primer post for a rundown on validator security.

Isomorphic Woes

One question I’ve asked myself is where do we put these allow and deny methods within our Meteor application? Intuitively, we may think that the best place to keep them is where we’ve defined our collections - in a shared location visible to the client and server. This seems to be a very common pattern amongst Meteor developers. You can even see it in Sacha’s allow & deny challenge final example. He’s defining his allow and deny methods for the Messages collection in common.js.

So what’s the big deal? Why does this matter? Well, imagine if your allow and deny methods weren’t completely secure. Would it be a good idea to ship those methods down to the client where any malicious user could browse through them at their convenience? Probably not, but that’s exactly what’s happening.

Open the allow and deny challenge MeteorPad, and in your browser’s console run the following statement:

> Messages._validators.update.allow[1].toString();
< "function (userId, doc, fields, modifier) {
    // log out checks
    console.log("// All checks must return true:");
    console.log(!_.contains(doc.likes, userId));
    console.log(_.keys(modifier).isEqualTo(["$addToSet", "$inc"]));
    console.log(modifier.$addToSet.likes === userId);
    console.log(modifier.$inc.likesCount === 1);
    var check = 
      userId &&
      !_.contains(doc.likes, userId) &&
      _.keys(modifier).isEqualTo(["$addToSet", "$inc"]) &&
      _.keys(modifier.$addToSet).isEqualTo(["likes"]) &&
      _.keys(modifier.$inc).isEqualTo(["likesCount"]) &&
      modifier.$addToSet.likes === userId &&
      modifier.$inc.likesCount === 1;
    return check;

You’ll notice that the entire source of the allow function is visible to the client! Take some time and explore the _validators object. You’ll notice that all allow and deny methods for the Messages collection are being passed to the client.

Server-side Solution

The correct place to keep your allow and deny methods is on the server. Peruse through the official docs and read the wording surrounding the allow and deny methods. Notice that they’re specifically marked as server functionality.

When a client calls insert, update, or remove on a collection, the collection’s allow and deny callbacks are called on the server to determine if the write should be allowed.

By keeping your methods on the server, a malicious user will not be given to opportunity to dig through them with a fine-toothed comb. They would be reduced to manual testing or fuzzing to find vulnerabilities in your collection validators.

I feel it’s important for me to mention that I’m not advocating hiding your allow and deny methods as an alternative to properly securing them. You should do your absolute best to correctly secure your validators. Moving them to the server simply gives you a small layer of protection against attackers and makes their job slightly harder. Remember, security through obscurity is not security.

Meteor Club Podcast - Talking Security