Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
chaosrouter
Advanced tools
npm install chaosrouter --save
By initializing with a file path instead of an object, ChaosRouter can reload the config file file whenever there is a change. Using an object would require restarting the server everytime it changed.
var chaosrouter = require('chaosrouter');
var router = chaosrouter({
"api": {
"helloworld": {
"__response__": "Hello World!"
}
}
});
// Load JSON from a file
var router = chaosrouter('./routes.json');
var chaosrouter = require('chaosrouter');
// Load several modules
chaosrouter.modules('module1', 'module2', ...);
// Load one at a time
chaosrouter.module('module1');
chaosrouter.module('module2');
chaosrouter.module(...);
Directives are not enabled automatically, for good reason. Let's say you have 2 modules you like but they both have a directive with the same name. If they loaded automatically, one would overwrite the other. In order to prevent this overwrite, you would have to know every directive that every module is loading. You would have to manually disable the one in the module you don't want, and enable the one in the module you do want. To be safe all the time, directives have to be enabled on a per module basis.
// Enable all directives
router.module('module1', router.ENABLE_ALL);
// Enable all directives
router.modules('module1');
router.modules({
'module1': true,
});
router.module('module1', router.ENABLE_ALL);
router.module('module1', true);
// Enable specific directives
router.modules({
'module1': ['directive1', 'directive2', ...],
});
router.module('module1', {
enable: ['directive1', 'directive2', ...],
});
router.module('module1', router.ENABLE_SELECTION, ['directive1', 'directive2', ...]);
// Enable all excluding specific directives
router.modules({
'module1 ^': ['directive1', 'directive2', ...],
});
router.module('module1', {
exclude: ['directive1', 'directive2', ...],
});
router.module('module1', router.ENABLE_EXCLUSION, ['directive1', 'directive2', ...]);
// Disable specific directives
router.modules({
'module1 !': ['directive1', 'directive2', ...],
});
router.module('module1', {
disable: ['directive1', 'directive2', ...],
});
router.module('module1', router.DISABLE_SELECTION, ['directive1', 'directive2', ...]);
var module1 = router.module('module1');
module1.run_some_method_on_the_module();
Here is a simple example of using ChaosRouter to return simple, static text for an endpoint. We will break down what is happening:
__response__
directiveInstead of defining your own directives, you can load the 'chaosrouter-base' module and use our standard directive implementations. See Loading Modules (See section ) section and the ChaosRouter Libs (See section ) Documentation.
var chaosrouter = require('chaosrouter');
var router = chaosrouter({
"api": {
"helloworld": {
"__response__": "Hello World!"
}
}
});
router.directive('response', function(text, _, resolve) {
resolve(text);
});
// Get the Draft Node for route path /api/helloworld
var draft = router.route('/api/helloworld');
# draft.run().then(...
# draft.execute().then(...
# draft.make().then(...
# draft.create().then(...
# draft.go().then(...
# draft.complete().then(...
# draft.finish().then(...
# draft.then(...
draft.proceed().then(function(data) {
console.log(data); // == "Hello World!"
});
This Object represents a specific point in the routes configuration. A Draft Node contains all the directive instructions for that configuration point.
var chaosrouter = require('chaosrouter');
var router = chaosrouter({
"user": {
"__pre__": true,
"__response__": { "1": "Robin Williams" },
":id": {
"__response__": {
"id": "< path.id",
"name": "Robin Williams",
"wikipedia": "https://en.wikipedia.org/wiki/Robin_Williams"
}
}
}
});
var draft = router.route('/user');
draft.ready(function() {
draft.id(); // /users
draft.path; // /users
draft.raw_path; // /users
draft.segments() // [ 'users' ]
draft.raw_segments() // [ 'users' ]
draft.params; // {}
draft.raw // { "__pre__": true, "__response__": { ... }, ":id": { ... } }
draft.router; // Router Object
draft.directives(); // { "pre": true, "response": { "1": "Robin Williams" } }
draft.directive('response'); // { "1": "Robin Williams" }
draft.directive('post'); // null
draft.parent(); // router.route('/')
draft.parents(); // [ router.route('/') ]
draft.children(); // [ ':id' ]
draft.child('1'); // router.route('/user/1')
});
var draft = router.route('/user/1');
draft.ready(function() {
draft.id(); // /users/1
draft.path; // /users/1
draft.raw_path; // /users/:id
draft.segments() // [ 'users', '1' ]
draft.raw_segments() // [ 'users', ':id' ]
draft.params; // { "id": "1" }
draft.raw // { "__response__": { "id": "< path.id", "name": "Robin Williams", ... } }
draft.router; // Router Object
draft.directives(); // { "response": { "id": "< path.id", "name": "Robin Williams", ... } }
draft.parent(); // router.route('/user')
draft.parents(); // [ router.route('/user'), router.route('/') ]
draft.children(); // []
draft.child('anything'); // null
});
// Relative routing
var draft = draft.route('../2');
Directives are power behind ChaosRouter! There is virtually no limit to what you can make a directive do. Within a directive, there is access to all router resources and configurations. With that access you can program directives to do just about anything, even dynamically configure other directives.
var chaosrouter = require('chaosrouter');
var router = chaosrouter(<config>);
router.directive(<key / name>, function(config) {
// 'this' is the Draft node
// 'config' is the value from this directive in the current Draft
// ... do things based on config
// this.next() to move onto the next directive
// return this.resolve(...) to end here with result [...]
// return this.reject(...) to end here with error [...]
});
A module is simply an object with the name of the module, and a dictionary of directive names and functions. The module name is the unique name that will be used to reference the module after it is loaded. When ChaosRouter loads a module, it will call the export function passing itself as the first argument. It is important to have access to the ChoasRouter module to have full control. For instance, a module could load several other modules, or use the 'restuct-data' and 'populater' modules that are loaded in the ChaosRouter module.
module.exports = function(chaosrouter) {
return {
"__name__": <module ID>,
"__init__": function() {
...
},
"__enable__": function(method) {
...
},
"__disable__": function(method) {
...
},
"__directives__": {
<directive name>: function(<config>) {
...
},
<directive name>: {
"__before__": function(<config>) {
...
},
"__runtime__": function(<config>) {
...
},
"__after__": function(<config>) {
...
},
},
...
},
<key1>: <value1>,
<key2>: function() {
return <value2>;
},
...
};
};
You can access anything inside the module using
var module = router.module(<module ID>);
module.<key1>; // <value1>
module.<key2>(); // <value2>
FAQs
Customizable, cross platform, web server routing framework
We found that chaosrouter demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.