Skip to content

Commit

Permalink
lib: make validateObject less affected by prototype tampering
Browse files Browse the repository at this point in the history
PR-URL: #42929
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
  • Loading branch information
aduh95 authored and targos committed Sep 16, 2022
1 parent 9ed48e3 commit ab78589
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
14 changes: 10 additions & 4 deletions lib/internal/validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const {
NumberMAX_SAFE_INTEGER,
NumberMIN_SAFE_INTEGER,
NumberParseInt,
ObjectPrototypeHasOwnProperty,
RegExpPrototypeExec,
String,
StringPrototypeToUpperCase,
Expand Down Expand Up @@ -150,6 +151,12 @@ function validateBoolean(value, name) {
throw new ERR_INVALID_ARG_TYPE(name, 'boolean', value);
}

function getOwnPropertyValueOrDefault(options, key, defaultValue) {
return options == null || !ObjectPrototypeHasOwnProperty(options, key) ?
defaultValue :
options[key];
}

/**
* @param {unknown} value
* @param {string} name
Expand All @@ -161,10 +168,9 @@ function validateBoolean(value, name) {
*/
const validateObject = hideStackFrames(
(value, name, options) => {
const useDefaultOptions = options == null;
const allowArray = useDefaultOptions ? false : options.allowArray;
const allowFunction = useDefaultOptions ? false : options.allowFunction;
const nullable = useDefaultOptions ? false : options.nullable;
const allowArray = getOwnPropertyValueOrDefault(options, 'allowArray', false);
const allowFunction = getOwnPropertyValueOrDefault(options, 'allowFunction', false);
const nullable = getOwnPropertyValueOrDefault(options, 'nullable', false);
if ((!nullable && value === null) ||
(!allowArray && ArrayIsArray(value)) ||
(typeof value !== 'object' && (
Expand Down
13 changes: 13 additions & 0 deletions test/parallel/test-validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ const invalidArgValueError = {

{
// validateObject tests.
Object.prototype.nullable = true;
Object.prototype.allowArray = true;
Object.prototype.allowFunction = true;

validateObject({}, 'foo');
validateObject({ a: 42, b: 'foo' }, 'foo');

Expand All @@ -119,6 +123,15 @@ const invalidArgValueError = {
validateObject(null, 'foo', { nullable: true });
validateObject([], 'foo', { allowArray: true });
validateObject(() => {}, 'foo', { allowFunction: true });

// validateObject should not be affected by Object.prototype tampering.
assert.throws(() => validateObject(null, 'foo', { allowArray: true }), invalidArgTypeError);
assert.throws(() => validateObject([], 'foo', { nullable: true }), invalidArgTypeError);
assert.throws(() => validateObject(() => {}, 'foo', { nullable: true }), invalidArgTypeError);

delete Object.prototype.nullable;
delete Object.prototype.allowArray;
delete Object.prototype.allowFunction;
}

{
Expand Down

0 comments on commit ab78589

Please sign in to comment.