The binary file can't be used as a CommonJS module because it has a shebang (#! /usr/bin/env node
) at the top, which is an invalid syntax for JavaScript. That is why they are not considered when building a dependency tree of the application. The application fails when it tries to run test binary such as mocha
because Mininode removed required dependencies.
- Issue: #65
- Commit: still working on automatic
Solution: The idea behind the solution is to install devDependencies as global packages. In this way mocha
or other executable JS files required for testing will not fail because Mininode will not reduce it. Additionally, because of executable JS files cannot be used as a required module we can remove them from node_modules folder "safely". However, if executable JS files are called indirectly from modules using child_processes
, our solution will break the application.
Dynamic manipulation happens when the required module is passed to some dynamic function. The dynamic function is a function which is not defined inside the requested module.
var utils = require('utils');
foo(utils); // we don't know what will happen inside foo function.
Example: debug module.
Example:
// in malware.js
var express = require(express'');
express.get = function() {
// rewrite original get to any functionality
}
When require is passed a variable.
var a = null;
if (b === 0)
a = 'bar'
else
a = 'foo'
const c = require(a)
// in index.js
var foo = require('foo'), bar = require('bar');
foo.x()
bar.a()
// in foo.js
var bar = require('bar');
exports.x = function(){}
exports.y = function(){}
// in bar.js
var foo = require('foo')
exports.a = function() {}
exports.b = function() {
foo.y()
}
Example:
var es = exports, flatmap = require('flatmap-stream');
es.flatmap = flatmap;
There may be diffirent ways to dynamically export the functionality. Example:
var member = 'foo';
exports[member];
Example:
// inside a.js
let foo = require('foo');
bar = require('bar'); // globally requiring
globalFoo = foo; // global variable
// inside b.js
bar.a(); // should detect this.
globalFoo.b() // should detect this