Skip to content

Commit c8cbec4

Browse files
aduh95targos
authored andcommitted
lib: make validateObject less affected by prototype tampering
PR-URL: #42929 Reviewed-By: Tobias Nießen <tniessen@tnie.de>
1 parent 1bd5633 commit c8cbec4

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

lib/internal/validators.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const {
99
NumberMAX_SAFE_INTEGER,
1010
NumberMIN_SAFE_INTEGER,
1111
NumberParseInt,
12+
ObjectPrototypeHasOwnProperty,
1213
RegExpPrototypeExec,
1314
String,
1415
StringPrototypeToUpperCase,
@@ -135,6 +136,12 @@ function validateBoolean(value, name) {
135136
throw new ERR_INVALID_ARG_TYPE(name, 'boolean', value);
136137
}
137138

139+
function getOwnPropertyValueOrDefault(options, key, defaultValue) {
140+
return options == null || !ObjectPrototypeHasOwnProperty(options, key) ?
141+
defaultValue :
142+
options[key];
143+
}
144+
138145
/**
139146
* @param {unknown} value
140147
* @param {string} name
@@ -146,10 +153,9 @@ function validateBoolean(value, name) {
146153
*/
147154
const validateObject = hideStackFrames(
148155
(value, name, options) => {
149-
const useDefaultOptions = options == null;
150-
const allowArray = useDefaultOptions ? false : options.allowArray;
151-
const allowFunction = useDefaultOptions ? false : options.allowFunction;
152-
const nullable = useDefaultOptions ? false : options.nullable;
156+
const allowArray = getOwnPropertyValueOrDefault(options, 'allowArray', false);
157+
const allowFunction = getOwnPropertyValueOrDefault(options, 'allowFunction', false);
158+
const nullable = getOwnPropertyValueOrDefault(options, 'nullable', false);
153159
if ((!nullable && value === null) ||
154160
(!allowArray && ArrayIsArray(value)) ||
155161
(typeof value !== 'object' && (

test/parallel/test-validators.js

+13
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ const invalidArgValueError = {
105105

106106
{
107107
// validateObject tests.
108+
Object.prototype.nullable = true;
109+
Object.prototype.allowArray = true;
110+
Object.prototype.allowFunction = true;
111+
108112
validateObject({}, 'foo');
109113
validateObject({ a: 42, b: 'foo' }, 'foo');
110114

@@ -119,6 +123,15 @@ const invalidArgValueError = {
119123
validateObject(null, 'foo', { nullable: true });
120124
validateObject([], 'foo', { allowArray: true });
121125
validateObject(() => {}, 'foo', { allowFunction: true });
126+
127+
// validateObject should not be affected by Object.prototype tampering.
128+
assert.throws(() => validateObject(null, 'foo', { allowArray: true }), invalidArgTypeError);
129+
assert.throws(() => validateObject([], 'foo', { nullable: true }), invalidArgTypeError);
130+
assert.throws(() => validateObject(() => {}, 'foo', { nullable: true }), invalidArgTypeError);
131+
132+
delete Object.prototype.nullable;
133+
delete Object.prototype.allowArray;
134+
delete Object.prototype.allowFunction;
122135
}
123136

124137
{

0 commit comments

Comments
 (0)