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.
A generic configuration system for Node.js.
Cerebro receives two inputs:
dimension
.Cerebro outputs the resolved configuration.
import Cerebro from 'cerebro';
const configuration = [{
setting: 'timer',
value: 30,
except: [{
value: 15,
environment: ['alpha']
}]
}];
const context = {
environment: 'alpha'
};
// initialize Cerebro
const cerebro = new Cerebro(configuration);
const resolvedConfiguration = cerebro.resolveConfig(context);
console.log(resolvedConfiguration);
// -> { timer: 15 } because the setting `timer` is set to 15 when the environment is alpha.
// for all other environments, the resolvedConfiguration would be { timer: 30 }
For configuration, Cerebro expects an array that contains objects that have a setting
and a value
. setting
is the name of the configuration setting, and value
is the value that will be assigned to it. value
can be any JSON data type.
Here is an example configuration object:
[{
setting: 'timer',
value: 30,
except: [{
value: 15,
environment: ['alpha']
}]
}]
Settings must explicitly set the value in the except
blocks.
Settings are expected to follow these rules:
Settings are defined formally in src/validators/schema.json
.
If all the criteria in an except
block is met, the value in the except block will be used. The except blocks are checked in order, and it exits once it finds a match. If no except
block matches fully, then the default value is used.
Here is an example:
import Cerebro from ('cerebro');
const configuration = [{
setting: 'timer',
value: 30,
except: [{
value: 15,
environment: ['alpha']
}, {
value: 20,
environment: ['alpha'],
bucket: 'a'
}]
}];
const context = {
environment: 'alpha',
bucket: 'a'
};
// initialize Cerebro
const cerebro = new Cerebro(configuration);
const resolvedConfiguration = cerebro.resolveConfig(context);
console.log(resolvedConfiguration);
// -> { timer: 15 } because the setting `timer` is set to 15 when the environment is alpha.
// in this case, {timer: 20} would never be hit because {timer: 15} will cause the evaluation
// to end immediately when environment is alpha
Given an except block that accepts multiple values for the same dimension, enable the setting if a dimension in the context object matches one of those values. For example, if the configuration has something like this:
[{
setting: 'enableNewFeature',
value: false,
except: [{
value: true,
bucket: ['a', 'b']
}]
}];
The setting should be enabled if the context object contains the dimension bucket: 'a'
or bucket: 'b'
.
Enums also support two additional options, none
and all
. Here's what the configuration would look like:
[{
setting: 'enableNewFeature',
value: false,
except: [{
value: true,
partner: [
'all'
]
}]
}];
In this case, if the context object contains any partner, the setting will be enabled. If the context contains no partner, the setting will be disabled. In other words, the setting is only enabled for partners.
[{
setting: 'enableNewFeature',
value: false,
except: [{
value: true,
partner: ['none']
}]
}];
Similar logic applies to none
. If the context contains no partner, the setting will be enabled. If the context contains any partner, the setting will be disabled. In other words, the setting is disabled only for partners.
A configuration may contain a range of values. The range may be inclusive or exclusive.
An inclusive range looks like this: rangeExample: ['1000..2000']
.
An exclusive range looks like this: rangeExample: ['1000...2000']
.
Here’s an example of a setting using a range:
[{
setting: 'enableNewFeature',
value: false,
except: [{
value: true,
userBirthdayYear: ['2000...2010']
}]
}];
Thus, if the context contains a dimension called userBirthdayYear
that is anywhere between 2000 and 2010, exclusive, the setting will be enabled.
One setting may depend on another setting. In this case, the configuration would look something like this:
[{
setting: 'independent',
value: false,
except: [{
value: true,
environment: ['alpha']
}]
}, {
setting: 'dependent',
value: false,
except: [{
value: true,
setting: 'independent'
}]
}];
In this case, the dependent setting will not be enabled unless the independent setting is also enabled.
We may want to evaluate a context in a custom way. For example, we may want to use do a partial string match using a regex.
Below is an example of the configuration:
[{
setting: 'enableNewFeature',
value: false,
except: [{
value: true,
partialLocale: ['en']
}]
}]
To use a custom evaluator, you must pass an object called customEvaluators
through the options
object in the Cerebro constructor. This object will have the name of the dimension it is to evaluate as a key and the evaluation function as value.
The evaluation function will receive two parameters, a dimensionValue
, which is the value given in the configuration (en
in the above example), and testValue
, which is the value passed in the context.
The evaluation function must return a boolean. If it does not return a boolean, the return value will be coerced to a boolean.
For the above configuration, the customEvaluators
would look like this:
var customEvaluators = { customDimension: function(dimensionValue, testValue) {} };
The dimensionValue
would be [“en”], and the testValue would be whatever the value of customDimension
was in the context.
We may want to override a certain setting, regardless of what the configuration says. To do this, the client must pass an object, overrides
, into the Cerebro constructor. The keys of the overrides
object will be the setting names and the value will be the value of the setting. Typically, these overrides would come from the request URL, but any source can be used.
Label metadata may be added to each entry in the form of an array of strings. This does not affect the evaluation of setting entries into their resulting values. It's stricly meant as a way to contextualize those values.
For instance, values that are not wanted as part of a client payload can be marked "server".
Note that this could be used to create subsets of values that no longer have all of the original entries with contraints such as dependencies.
An alternative way to organize and contextualize is to group settings into separate files.
[{
setting: 'enableNewFeature',
labels: ['server', 'namedFeatureGroup'],
value: false,
except: [{
value: true,
partialLocale: ['en']
}]
}]
This option is useful for having live configuration that updates without having to re-deploy your application. A poller object continuously calls a fetch
function to retrieve a newer version of the configuration. This is very open ended to allow for different security mechanisms such as mTLS or signed responses.
Optionally (but recommended), a configuration schema can be given to the poller to ensure that the response is a valid configuration.
const Cerebro = require('cerebro');
const poller = new Cerebro.ConfigPoller({
clientSchema: /* optional schema */,
interval: 5000,
fetch: async function() {
const response = await fetch(/* ... */);
return response.json();
}
});
const cerebro = new Cerebro(config, {
poller
});
FAQs
A generic configuration system for Node.js.
The npm package cerebro receives a total of 26 weekly downloads. As such, cerebro popularity was classified as not popular.
We found that cerebro demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers 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.