
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
propertiesmanager
Advanced tools
Powerful Node.js configuration management with multi-environment support, CLI/env overrides, multi-file composition, hot reload, and security features
A powerful and flexible Node.js configuration management module with support for multiple environments, command-line overrides, environment variables, multi-file composition, hot reload, and advanced security features.
PM_* environment variablesThis module helps to easily manage all the configuration properties needed in a system, giving a simple and consistent configuration interface to your application. The properties must have a profile category: production, dev, or test. Configuration files are stored in the config folder in your application home directory (config/default.json).
To install propertiesmanager, type:
$ npm install propertiesmanager
Configuration files must be created in a folder named config in the home directory of your application.
The filename must be named default.json. Type:
$ mkdir config
$ vi config/default.json
The file containing your properties is a JSON file having a mandatory dictionary called "production". It contains all the configuration parameters of your application running in production or default mode. Other dictionaries can be used, "dev" for development properties and "test" for testing properties.
An example of empty property file:
{
"production":{}
}
An example of populated property file:
{
"production":{
"properties_One":"One",
"properties_Two":"Two",
"Objectproperties":{
"Obj_One":1,
"Obj_Two":2
}
}
}
An example of property file with dev and test dictionaries defined:
{
"production":{
"properties_One":"One",
"properties_Two":"Two",
"Objectproperties":{
"Obj_One":1,
"Obj_Two":2
}
},
"test":{
"properties_One":"TestOne",
"Objectproperties":{
"Obj_One":1,
"Obj_Two":2
}
},
"dev":{
"properties_One":"Test Development",
"DevLogs":{
"path":"/logs/log.xml",
"format":"xml"
}
}
}
Just require it like a simple package:
var propertiesmanager = require('propertiesmanager').conf;
propertiesmanager returns a dictionary containing all the properties from a configuration file. These properties can be overridden by command line parameters.
// Print all the loaded properties
console.log(propertiesmanager);
The application using this package runs under one profile among three (production, dev, test), set by NODE_ENV environment variable. If NODE_ENV is not defined the default profile is production
Running your app in default mode. production properties are loaded:
$ cd "YOUR_APPLICATION_HOME_DIRECTORY"
$ npm start
Running your app in production mode. production properties are loaded:
$ cd "YOUR_APPLICATION_HOME_DIRECTORY"
$ NODE_ENV=production npm start
Running your app in dev mode. dev properties are loaded:
$ cd "YOUR_APPLICATION_HOME_DIRECTORY"
$ NODE_ENV=dev npm start
Running your app in test mode. test properties are loaded:
$ cd "YOUR_APPLICATION_HOME_DIRECTORY"
$ NODE_ENV=test npm start
The package propertiesmanager uses minimist for parsing command-line arguments, so your properties stored in default.json can be
overridden by command line parameters.
$ cd "YOUR_APPLICATION_HOME_DIRECTORY"
$ NODE_ENV=dev npm start -- --properties_One="Override_TestOne"
The first -- after npm start means that the following params must be passed to node bin/www,
so if you run your application directly calling node bin/www the first -- must be not used:
$ cd "YOUR_APPLICATION_HOME_DIRECTORY"
$ NODE_ENV=dev node bin/www --properties_One="Override_TestOne"
Since this package uses minimist, the following syntax rules apply:
--key=value → Sets key to "value" (string)--key=123 → Sets key to 123 (number - minimist auto-converts)--key=true → Sets key to "true" (string)--key=false → Sets key to "false" (string)--key → Sets key to true (boolean - flag syntax)--key=null → Sets key to null (actual null value, not string)--key=undefined → Sets key to undefined (actual undefined value, not string)--key= → Rejected (empty string not allowed by design)To override parameters that are complex objects, use dotted (".") notation:
// Example: We want to override Obj_One property
// This is the structure in default.json:
{
"production":{
"properties_One":"One",
"properties_Two":"Two",
"Objectproperties":{
"Obj_One":1,
"Obj_Two":2
}
}
}
// Command to override the Obj_One value
$ cd "YOUR_APPLICATION_HOME_DIRECTORY"
$ NODE_ENV=dev node bin/www --Objectproperties.Obj_One="Override_Obj_One"
For further information about minimist syntax, see the minimist documentation.
Properties can also be overridden using environment variables with the PM_ prefix. This is especially useful in containerized environments or CI/CD pipelines.
Precedence order (highest to lowest):
PM_*)# Override port via environment variable
$ PM_PORT=8080 node app.js
# Override nested properties (use uppercase for nested keys)
$ PM_DATABASE.HOST=localhost PM_DATABASE.PORT=5432 node app.js
# Combine with command line (command line has lower priority)
$ PM_PORT=8080 node app.js --database.name=mydb
# Set to null or undefined
$ PM_DATABASE.HOST=null node app.js
$ PM_CACHE.ENABLED=undefined node app.js
Environment variables are converted the same way as command-line parameters:
"null" string becomes null"undefined" string becomes undefinedThe package supports loading and merging multiple configuration files for better organization and security:
config/default.json - Base configuration (required)config/local.json - Local overrides (optional, not committed to git)config/secrets.json - Sensitive data like API keys (optional, not committed to git)Merge precedence (highest to lowest):
config/secrets.jsonconfig/local.jsonconfig/default.json// config/default.json (base configuration)
{"production": {"appName": "MyApp", "port": 3000, "db": {"host": "localhost"}}}
// config/local.json (developer overrides)
{"production": {"port": 8080, "db": {"host": "192.168.1.100"}}}
// config/secrets.json (credentials)
{"production": {"db": {"password": "secret123"}}}
// Result: port=8080, db.host=192.168.1.100, db.password=secret123
Best practices:
config/local.json and config/secrets.json to .gitignoredefault.json for safe default valueslocal.json for developer-specific settingssecrets.json for sensitive credentialsThe package can watch config/default.json for changes and automatically reload the configuration when the file is modified. Hot reload is disabled by default and must be explicitly enabled.
Enable via environment variable:
$ ENABLE_CONFIG_WATCH=true node app.js
Note: This must be set as an environment variable (not in config file) to avoid circular dependency issues.
var propertiesmanager = require('propertiesmanager');
// Listen for configuration reload events
propertiesmanager.configEvents.on('reload', function(newConfig) {
console.log('Configuration reloaded!');
console.log('New config:', newConfig);
// Update your application state with new config
// For example, restart a service, reconnect to database, etc.
});
// Access current configuration
console.log(propertiesmanager.conf);
config/default.json for changesreload event is emitted with the new configurationpropertiesmanager.conf (by reference)Note: Hot reload only watches config/default.json. Changes to local.json or secrets.json require an application restart.
Production use: Hot reload is disabled by default, making it safe for production. Only enable it in development environments where you need automatic configuration updates.
The package uses the LOG_LEVEL environment variable to control logging verbosity. This affects all internal messages from propertiesmanager.
Available levels (from most to least verbose): debug, info, warn, error
Default: info
Set via LOG_LEVEL environment variable:
# Debug mode: show all internal messages (key processing, config loading, watcher status)
$ LOG_LEVEL=debug node app.js
# Default: info level (shows config loaded, hot-reload events)
$ LOG_LEVEL=info node app.js
# Production: only errors and warnings
$ LOG_LEVEL=warn node app.js
# Only critical errors
$ LOG_LEVEL=error node app.js
Note: LOG_LEVEL must be set as an environment variable and cannot be configured in the config file.
When LOG_LEVEL=debug is set, you'll see detailed internal messages:
propertiesmanager Processing key: appName
propertiesmanager Processing key: server
propertiesmanager Config file watcher disabled (set ENABLE_CONFIG_WATCH=true to enable)
propertiesmanager Configuration loaded successfully for environment: production
These messages show the internal workings of the configuration loading process and are useful for troubleshooting.
The package includes TypeScript type definitions. TypeScript projects can import and use it with full type support:
import { conf } from 'propertiesmanager';
// conf is typed as Record<string, any>
const port: number = conf.server.port;
const appName: string = conf.appName;
For better type safety, you can define your own interface:
interface MyConfig {
appName: string;
server: {
host: string;
port: number;
};
database: {
host: string;
name: string;
};
}
import { conf } from 'propertiesmanager';
const config = conf as MyConfig;
// Now fully typed!
const port: number = config.server.port;
propertiesmanager implements multiple security protections to prevent common configuration-based attacks:
The package actively blocks attempts to pollute JavaScript prototypes through command-line arguments:
__proto__ - Automatically filtered and rejectedconstructor - Blocked at all nesting levelsprototype - Cannot be used as property nameThese protections prevent attackers from injecting malicious properties into JavaScript's object prototype chain, which could lead to:
# These malicious attempts are automatically blocked:
$ node app.js --__proto__.polluted=true # ❌ BLOCKED
$ node app.js --constructor.prototype.admin=true # ❌ BLOCKED
$ node app.js --prototype.isAdmin=true # ❌ BLOCKED
The package only allows overriding existing properties defined in default.json:
// If default.json contains:
{
"production": {
"port": 3000,
"debug": false
}
}
// This works (overrides existing property):
$ node app.js --port=8080 // ✅ OK
// This is silently ignored (property doesn't exist):
$ node app.js --malicious=payload // ❌ IGNORED
Empty values via --key= syntax are rejected by design to prevent accidental configuration corruption:
$ node app.js --database.host= # ❌ REJECTED (empty string)
$ node app.js --database.host=null # ✅ OK (explicit null)
The package safely handles path-like strings and prevents directory traversal attempts:
$ node app.js --configPath=../../etc/passwd # ✅ Treated as safe string value
SQL injection, XSS, and other injection patterns are safely handled as regular string values without special interpretation.
All security features are validated through 119 automated tests, including specific vulnerability tests in test/security-integrity.test.js and logging configuration tests in test/logging.test.js.
The package provides clear error messages when configuration files are missing or invalid:
ERROR: config/default.json not found or invalid.
Please create config/default.json in your application root directory.
See https://github.com/aromanino/propertiesmanager for documentation.
This prevents silent failures and helps developers quickly identify configuration issues.
From your home project directory type:
$ mkdir config
$ vi config/default.json
Write default.json property file:
{
"production":{
"properties_One":"One",
"properties_Two":"Two",
"Objectproperties":{
"Obj_One":1,
"Obj_Two":2
}
},
"test":{
"properties_One":"TestOne",
"Objectproperties":{
"Obj_One":1,
"Obj_Two":2
}
},
"dev":{
"properties_One":"Test Development",
"DevLogs":{
"path":"/logs/log.xml",
"format":"xml"
}
}
}
Now you can print all your properties:
var propertiesmanager = require('propertiesmanager').conf;
// Print the loaded properties to console
console.log("########### Read Properties ###########" );
console.log(propertiesmanager);
Running your app in default mode, production properties are loaded:
$ cd "YOUR_APPLICATION_HOME_DIRECTORY"
$ npm start
########### Read Properties ###########
"production":{
"properties_One":"One",
"properties_Two":"Two",
"Objectproperties":{
"Obj_One":1,
"Obj_Two":2
}
}
Running your app in production mode (NODE_ENV=production) is equivalent to run in default mode:
$ cd "YOUR_APPLICATION_HOME_DIRECTORY"
$ NODE_ENV=production npm start
########### Read Properties ###########
"production":{
"properties_One":"One",
"properties_Two":"Two",
"Objectproperties":{
"Obj_One":1,
"Obj_Two":2
}
}
Running your app in dev mode (NODE_ENV=dev), dev properties are loaded:
$ cd "YOUR_APPLICATION_HOME_DIRECTORY"
$ NODE_ENV=dev npm start
########### Read Properties ###########
"dev":{
"properties_One":"Test Development",
"DevLogs":{
"path":"/logs/log.xml",
"format":"xml"
}
}
Running your app in test mode (NODE_ENV=test), test properties are loaded:
$ cd "YOUR_APPLICATION_HOME_DIRECTORY"
$ NODE_ENV=test npm start
########### Read Properties ###########
"test":{
"properties_One":"TestOne",
"Objectproperties":{
"Obj_One":1,
"Obj_Two":2
}
}
Overriding some test mode (NODE_ENV=test) properties:
$ cd "YOUR_APPLICATION_HOME_DIRECTORY"
$ NODE_ENV=test npm start -- --properties_One="Override_TestOne"
########### Read Properties ###########
"test":{
"properties_One":"Override_TestOne",
"Objectproperties":{
"Obj_One":1,
"Obj_Two":2
}
}
MIT License
Copyright (c) 2016 aromanino
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
CRS4 Microservice Core Team (cmc.smartenv@crs4.it)
Alessandro Romanino (a.romanino@gmail.com)
Guido Porruvecchio (guido.porruvecchio@gmail.com)
FAQs
Powerful Node.js configuration management with multi-environment support, CLI/env overrides, multi-file composition, hot reload, and security features
We found that propertiesmanager demonstrated a healthy version release cadence and project activity because the last version was released less than 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
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.