Scanning Meteor Projects for Node Vulnerabilities

Written by Pete Corey on Dec 7, 2015.

Meteor does not exist in a bubble. All of Meteor is built on top of Node.js. This means that while security projects like east5th:package-scan can help us find Meteor specific security problems in our projects, we may still be vulnerable to an entire world of vulnerabilities that exist within the Node ecosystem.

There are many Node tools that, like east5th:package-scan, will dig through the Node packages being used by your project and alert you if it finds any packages with known security vulnerabilities.

Two great tools that do this are the Node Security Project and Snyk. While these tools are designed to be used with a vanilla Node project, with a little convincing it’s possible to use them in the context of a Meteor project.

Anatomy of a Bundle

It can be difficult to determine which Node packages are being used by a Meteor application. Each Meteor package can pull in its own set of Npm packages, and these dependencies can be difficult to see unless the Meteor package has been explicitly cloned into the PACKAGE_DIRS directory.

Thankfully, a bundled Meteor application pulls all of these dependencies into a single location. Once an application is bundled, we can dig into the server Node project (found in .build/bundle/programs/server). From there we can browse through all of the Node dependencies being used by our various Meteor packages: npm/*/node_modules/*.

A brand new Meteor project (meteor create foo) immediately pulls in over a dozen Node packages. Check them out:

.
├── babel-compiler         <- Meteor package
│   └── node_modules
│       └── meteor-babel   <- Node package
├── ddp-client
│   └── node_modules
│       ├── faye-websocket
│       └── permessage-deflate
├── ddp-server
│   └── node_modules
│       ├── permessage-deflate
│       └── sockjs
├── ecmascript-runtime
│   └── node_modules
│       └── meteor-ecmascript-runtime
├── es5-shim
│   └── node_modules
│       └── es5-shim
├── logging
│   └── node_modules
│       └── cli-color
├── meteor
│   └── node_modules
│       └── meteor-deque
├── mongo
│   └── node_modules
│       └── mongodb-uri
├── npm-mongo
│   └── node_modules
│       └── mongodb
├── promise
│   └── node_modules
│       └── meteor-promise
└── webapp
    └── node_modules
        ├── connect
        ├── send
        └── useragent

Using Node Security Project

We can navigate into any of these Node package directories and run an NSP scan. For example, we can check the sockjs package use by ddp-server like this:

cd .build/bundle/programs/server/npm/ddp-server/node_modules/sockjs
nsp check

Thankfully, there are no known vulnerabilities in this Node package:

(+) No known vulnerabilities found

We could manually run this check for each Node package, but that would be incredibly time consuming. Why not automate the process?

I wrote a quick bash script that looks for each package.json found within these top-level Node project folders and runs NSP on them. Here’s the script:

#!/usr/bin/env bash

find bundle/programs/server/npm/*/node_modules/*/package.json |
while read file; do
  DIR="$(dirname $file)"
  pushd "${DIR}" > /dev/null
  OUTPUT="$(nsp check --output summary --color)"
  if [ $? != 0 ]; then
    echo -e "${OUTPUT}"
  fi
  popd > /dev/null
done

I named this script mscan and threw it into my ~/bin folder. To use it, build your meteor project, navigate into the newly created build directory, and run the script:

meteor build --directory .build &&
cd .build &&
mscan

Even for a brand new Meteor project, the results of this scan are somewhat suprising:

(+) 3 vulnerabilities found
 Name        Installed   Patched     Path   More Info
 uglify-js   2.2.5       >=2.6.0            https://nodesecurity.io/advisories/48
 uglify-js   2.2.5       >= 2.4.24          https://nodesecurity.io/advisories/39
 uglify-js   2.4.24      >=2.6.0            https://nodesecurity.io/advisories/48


(+) 4 vulnerabilities found
 Name   Installed   Patched    Path             More Info
 send   0.1.4       >=0.11.1   connect > send   https://nodesecurity.io/advisories/56
 send   0.1.4       >= 0.8.4   connect > send   https://nodesecurity.io/advisories/32
 qs     0.6.5       >= 1.x     connect > qs     https://nodesecurity.io/advisories/28
 qs     0.6.5       >= 1.x     connect > qs     https://nodesecurity.io/advisories/29

It looks like Meteor core is pulling in a few Node packages with known security issues. Very interesting! It’s worth taking a look at these advisories and considering what impact (if any) they might have on your Meteor application.

Drawbacks and Final Thoughts

One thing to note about the NSP tool is that it will only scan the dependencies found in a package.json file for vulnerabilities. It will not check if the package itself has any known issues. This means that if we run nsp check on the mongodb Node package, it will only report any vulnerabilities in mongodb’s dependencies, not any vulnerabilities with the package itself.

This is a known issue and the Node Security Project team are actively working on a fix.

The bash script I created to do these scans certainly isn’t the most user friendly tool. If you find it interesting or useful, I can give it a little more love and turn it into a Npm-installable command line tool, which may be more straight-forward to use.

Giving Thanks

Written by Pete Corey on Nov 30, 2015.

Maybe it’s the pumpkin pie talking, but the spirit of thankfulness is flowing through me today. I want to take a minute to stop and reflect on the past year and give thanks where thanks is due.


A little over one year ago I started seriously experimenting with Meteor as a platform. Coming from a Java and PHP background and cobbling together front-ends with everything from Flex to AngluarJS and everything in-between, Meteor was a breath of fresh air. It let me focus on getting things done, rather than focusing on how to get things done.

The productivity boost I experienced when switching to Meteor was a game changer for my career. At the same time I was first digging into Meteor I decided to pursue full-time self employment. I opened up shop under the East5th name, and after my first year of business, I fully recognize that much of my success as a freelance developer and consultant is thanks to the technical foundation Meteor and the Meteor Development Group built out for me.

Thank you Meteor!


I’ve spent this past year intentionally investing more time into writing and creating content, and the results have been spectacular. Taking the time each week to write small blog posts and articles about various Meteor and software development topics has led to a huge outpouring of support and acceptance from the community.

On average, this blog gets approximately four thousand readers per month, and many of those people have become my close friends and colleagues. Many of those friends have offered invaluable help and advice throughout the year. I’m sincerely grateful to everything they’ve done for me, what they’ve helped me accomplish, and the opportunities they’ve given me.

Every Monday morning I push out some piece of content and eagerly wait for feedback from all of you. Your comments, questions, and suggestions truly help me grow as a developer. Hopefully something I write helps you as well.

I’m unimaginably excited about what the next few years will bring, and I hope I get to know a lot of you much better during that time!

If you want to get in touch, tweet me, or shoot me an email.

Thanks for reading!

Building Check-Checker as a Meteor Plugin

Written by Pete Corey on Nov 23, 2015.

I recently decided to switch my east5th:check-checker package to use the new Build Plugin API.

Before switching to the new linter API, I was using ESLint’s CLIEngine to power check-checker. This resulted in a few bugs due to assumptions CLIEngine made about its environment. I decided to ditch CLIEngine and have Meteor’s new linter API do the heavy lifting of delivering the files that need to be checked.

Buried deep within the Meteor wiki, there’s a fantastic guide for working with the new Build Plugin API. This wiki entry, combined with the jshint package were my guiding lights for this refactor.


The first step to turning a package into a linter is to modify your package.js. Linters, minifiers, and compilers are all considered “plugins” within the Meteor ecosystem, and need to be registered as such. This is done through a call to Package.registerBuildPlugin:

Package.registerBuildPlugin({
 name: "check-checker",
 sources: [
   "lib/rules/checks.js",
   "lib/check-checker.js"
 ],
 npmDependencies: {
   eslint: "0.24.1"
 }
});

Package.onUse(function(api) {
 api.use("isobuild:linter-plugin@1.0.0");
});

In our package code, we register our linter with a call to Plugin.registerLinter. We pass in the types of files we want to operate on, the architectures we want to look for these files in, and a function that returns an instance of our linter.

By specifying an architecture of "os", our linter will only rerun when changes are made to server code. Client source files will be ignored.

Plugin.registerLinter({
 extensions: ["js"],
 archMatching: "os"
}, function() {
 return new CheckChecker();
});

This last argument is the most important. You’ll notice that we’re returning a new instance of a CheckChecker function. Later on, we add a function to CheckChecker.prototype called processFilesForPackage.

This function is called directly by the linter for each set of files that match the criteria we specified above. The goal of our linter is to iterate over each of these files, looking for missing calls to check. When we find a problem we report it through a call to the error function with is attached automatically to each file instance we’re given.

function CheckChecker() {
 eslint.linter.defineRule('checks', checks);
};

CheckChecker.prototype.processFilesForPackage = function(files, options) {
...
 files.forEach(function(file) {
   var source = file.getContentsAsString();
   var path = file.getPathInPackage();
   var results = eslint.linter.verify(source, config, path);
   results.forEach(function(result) {
     file.error({
       message: result.message,
       line: result.line,
       column: result.column
     });
   });
 });
};

The rest of the processFilesForPackage function is ESLint specific and fairly uninteresting. We’re setting up a configuration object, and verifying that the give file complies with all of the rules we’ve created.

If you dig through the check-checker source, you’ll notice that I’m using getSourceHash to accomplish some basic in-memory caching. The goal here is to prevent ESLint from running on files it’s already verified. It’s recommended that you do some kind of caching to keep build times as fast as possible.


Creating linters using Meteor’s new Build Plugin API is a fairly straight-forward and painless process. I highly recommend taking a look at Build Plugin API wiki entry and the jshint package as an example implementation.

If you want another example of a linter using the Batch Plugin API, check out east5th:check-checker!