Security: special keys (toString/hasOwnProperty/constructor) pollute global process.env
Package: dotenv-parse-variables@2.0.0
Severity: High (process-wide Denial of Service)
Type: Special key handling — writes unfiltered keys into global process.env
Summary
dotenv-parse-variables parses keys from an env object and, by default (assignToProcessEnv: true), writes them back into the global process.env without filtering special keys. An .env file (or any env object) containing keys like toString, valueOf, hasOwnProperty, or constructor overwrites those built-in methods on the global process.env object with string values — affecting the entire process, not just the returned object.
Location
lib/index.js:32 and lib/index.js:35-41:
parsed[key] = parseKey(env[key], key); // line 32 — no key filter
if (envOptions.assignToProcessEnv === true) { // line 35 — default true
if (envOptions.overrideProcessEnv === true) {
process.env[key] = parsed[key] || process.env[key]; // line 37
} else {
process.env[key] = process.env[key] || parsed[key]; // line 39
}
}
Proof of concept
const parse = require('dotenv-parse-variables');
// Before: process.env methods intact
console.log(typeof process.env.toString); // "function"
// Parse a poisoned env object (e.g. loaded from an attacker-influenced .env)
parse({
APP_NAME: 'MyApp',
toString: 'EVIL',
hasOwnProperty: 'nope',
constructor: 'evil',
});
// After: global process.env methods are now strings
console.log(typeof process.env.toString); // "string" ← overwritten
console.log(typeof process.env.hasOwnProperty); // "string" ← overwritten
console.log(typeof process.env.constructor); // "string" ← overwritten
// Any code relying on process.env's built-in methods now crashes:
// `'ENV: ' + process.env` → TypeError: Cannot convert object to primitive value
Impact
- Process-wide DoS: any code that stringifies
process.env (logging, error reporting, serialization) or calls process.env.hasOwnProperty() (config checks) throws after a poisoned .env is loaded.
- Logic corruption:
constructor overwrite can break instanceof-style checks and object construction paths in libraries that walk process.env.
- Unlike a prototype-pollution-to-RCE, this does not escalate to code execution, but the blast radius (global shared object) is much wider than the returned-object-only case seen in other
.env parsers (env-file-parser, @tokey/env-file-parser, envfile — all have the same unfiltered-key assignment, but only this package writes to global process.env by default).
Suggested fix
const DANGEROUS_KEYS = new Set([
'__proto__', 'constructor', 'prototype',
'toString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
]);
// in the loop:
if (DANGEROUS_KEYS.has(key)) continue;
Note: process.env is not a plain object in Node (it's a special object), but process.env[key] = value for toString/hasOwnProperty/constructor still shadows the inherited methods process-wide.
Related
- Same class of issue (unfiltered keys, returned-object only) in:
env-file-parser@1.0.0 — lib/parse.js:32
@tokey/env-file-parser@2.0.0 — env-parser.js:183
envfile@7.1.0 — result[key] = value
- Attack surface:
.env content influenced via shared config templates, CI injection, or supply-chain (dependency writing .env at install).
Security: special keys (toString/hasOwnProperty/constructor) pollute global process.env
Package: dotenv-parse-variables@2.0.0
Severity: High (process-wide Denial of Service)
Type: Special key handling — writes unfiltered keys into global
process.envSummary
dotenv-parse-variablesparses keys from an env object and, by default (assignToProcessEnv: true), writes them back into the globalprocess.envwithout filtering special keys. An.envfile (or any env object) containing keys liketoString,valueOf,hasOwnProperty, orconstructoroverwrites those built-in methods on the globalprocess.envobject with string values — affecting the entire process, not just the returned object.Location
lib/index.js:32andlib/index.js:35-41:Proof of concept
Impact
process.env(logging, error reporting, serialization) or callsprocess.env.hasOwnProperty()(config checks) throws after a poisoned.envis loaded.constructoroverwrite can breakinstanceof-style checks and object construction paths in libraries that walkprocess.env..envparsers (env-file-parser,@tokey/env-file-parser,envfile— all have the same unfiltered-key assignment, but only this package writes to globalprocess.envby default).Suggested fix
Note:
process.envis not a plain object in Node (it's a special object), butprocess.env[key] = valuefortoString/hasOwnProperty/constructorstill shadows the inherited methods process-wide.Related
env-file-parser@1.0.0—lib/parse.js:32@tokey/env-file-parser@2.0.0—env-parser.js:183envfile@7.1.0—result[key] = value.envcontent influenced via shared config templates, CI injection, or supply-chain (dependency writing.envat install).