Skip to content

Commit 7b1aa13

Browse files
committed
fix(setup): prevent assigning value to __proto__
Assigning value to `__proto__` polutes `Object.prototype`. Reported by Daniel Elkabes from White Source Software.
1 parent 450cbd0 commit 7b1aa13

File tree

7 files changed

+38
-5
lines changed

7 files changed

+38
-5
lines changed

Diff for: built/setup.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import { normalizeDescriptor } from './utility/setup';
22
import { getNonEmptyPropName } from './utility/common';
3+
const propProto = '__proto__';
34
function generate(target, hierarchies, forceOverride) {
45
let current = target;
56
hierarchies.forEach(info => {
67
const descriptor = normalizeDescriptor(info);
78
const { value, type, create, override, created, skipped, got } = descriptor;
89
const name = getNonEmptyPropName(current, descriptor);
9-
if (forceOverride || override || !current[name] || typeof current[name] !== 'object') {
10+
if (forceOverride ||
11+
override ||
12+
!current[name] ||
13+
typeof current[name] !== 'object' ||
14+
(name === propProto && current[name] === Object.prototype)) {
1015
const obj = value ? value :
1116
type ? new type() :
1217
create ? create.call(current, current, name) :

Diff for: dist/index.esm.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,18 @@ function getPropNames(current, descriptor) {
7373
return getOwnEnumerablePropKeys(current);
7474
}
7575

76+
const propProto = '__proto__';
7677
function generate(target, hierarchies, forceOverride) {
7778
let current = target;
7879
hierarchies.forEach(info => {
7980
const descriptor = normalizeDescriptor(info);
8081
const { value, type, create, override, created, skipped, got } = descriptor;
8182
const name = getNonEmptyPropName(current, descriptor);
82-
if (forceOverride || override || !current[name] || typeof current[name] !== 'object') {
83+
if (forceOverride ||
84+
override ||
85+
!current[name] ||
86+
typeof current[name] !== 'object' ||
87+
(name === propProto && current[name] === Object.prototype)) {
8388
const obj = value ? value :
8489
type ? new type() :
8590
create ? create.call(current, current, name) :

Diff for: dist/index.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,18 @@
7979
return getOwnEnumerablePropKeys(current);
8080
}
8181

82+
var propProto = '__proto__';
8283
function generate(target, hierarchies, forceOverride) {
8384
var current = target;
8485
hierarchies.forEach(function (info) {
8586
var descriptor = normalizeDescriptor(info);
8687
var value = descriptor.value, type = descriptor.type, create = descriptor.create, override = descriptor.override, created = descriptor.created, skipped = descriptor.skipped, got = descriptor.got;
8788
var name = getNonEmptyPropName(current, descriptor);
88-
if (forceOverride || override || !current[name] || typeof current[name] !== 'object') {
89+
if (forceOverride ||
90+
override ||
91+
!current[name] ||
92+
typeof current[name] !== 'object' ||
93+
(name === propProto && current[name] === Object.prototype)) {
8994
var obj = value ? value :
9095
type ? new type() :
9196
create ? create.call(current, current, name) :

Diff for: dist/index.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: src/setup.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import type {SetupPropParam} from './type';
22
import {normalizeDescriptor} from './utility/setup';
33
import {getNonEmptyPropName} from './utility/common';
44

5+
const propProto = '__proto__';
6+
57
function generate(
68
target: any,
79
hierarchies: SetupPropParam[],
@@ -13,7 +15,13 @@ function generate(
1315
const {value, type, create, override, created, skipped, got} = descriptor;
1416

1517
const name = getNonEmptyPropName(current, descriptor);
16-
if (forceOverride || override || !current[name] || typeof current[name] !== 'object') {
18+
if (
19+
forceOverride ||
20+
override ||
21+
!current[name] ||
22+
typeof current[name] !== 'object' ||
23+
(name === propProto && current[name] === Object.prototype)
24+
) {
1725
const obj = value ? value :
1826
type ? new type() :
1927
create ? create.call(current, current, name) :

Diff for: test/set/7-no-proto-polution.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const assert = require('assert').strict;
2+
const {set} = require('../../');
3+
4+
const obj1 = {};
5+
const obj2 = {};
6+
set(obj1, '__proto__', 'admin', true);
7+
assert.notEqual(obj1.__proto__, Object.prototype);
8+
assert.equal(obj1.__proto__.admin, true);
9+
assert.strictEqual(obj2.admin, undefined);

Diff for: test/set/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ require('./3-symbol-property');
44
require('./4-array-params');
55
require('./5-array-value');
66
require('./6-option-params');
7+
require('./7-no-proto-polution');

0 commit comments

Comments
 (0)