Skip to content

Commit acff743

Browse files
aduh95juanarbol
authored andcommitted
lib: make validateObject less affected by prototype tampering
PR-URL: #42929 Reviewed-By: Tobias Nießen <[email protected]>
1 parent 8398e98 commit acff743

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
@@ -10,6 +10,7 @@ const {
1010
NumberMAX_SAFE_INTEGER,
1111
NumberMIN_SAFE_INTEGER,
1212
NumberParseInt,
13+
ObjectPrototypeHasOwnProperty,
1314
RegExpPrototypeExec,
1415
String,
1516
StringPrototypeToUpperCase,
@@ -150,6 +151,12 @@ function validateBoolean(value, name) {
150151
throw new ERR_INVALID_ARG_TYPE(name, 'boolean', value);
151152
}
152153

154+
function getOwnPropertyValueOrDefault(options, key, defaultValue) {
155+
return options == null || !ObjectPrototypeHasOwnProperty(options, key) ?
156+
defaultValue :
157+
options[key];
158+
}
159+
153160
/**
154161
* @param {unknown} value
155162
* @param {string} name
@@ -161,10 +168,9 @@ function validateBoolean(value, name) {
161168
*/
162169
const validateObject = hideStackFrames(
163170
(value, name, options) => {
164-
const useDefaultOptions = options == null;
165-
const allowArray = useDefaultOptions ? false : options.allowArray;
166-
const allowFunction = useDefaultOptions ? false : options.allowFunction;
167-
const nullable = useDefaultOptions ? false : options.nullable;
171+
const allowArray = getOwnPropertyValueOrDefault(options, 'allowArray', false);
172+
const allowFunction = getOwnPropertyValueOrDefault(options, 'allowFunction', false);
173+
const nullable = getOwnPropertyValueOrDefault(options, 'nullable', false);
168174
if ((!nullable && value === null) ||
169175
(!allowArray && ArrayIsArray(value)) ||
170176
(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)