• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4if ((!common.hasCrypto) || (!common.hasIntl)) {
5  common.skip('ESLint tests require crypto and Intl');
6}
7
8common.skipIfEslintMissing();
9
10const RuleTester = require('../../tools/node_modules/eslint').RuleTester;
11const rule = require('../../tools/eslint-rules/avoid-prototype-pollution');
12
13new RuleTester({
14  parserOptions: { ecmaVersion: 2022 },
15})
16  .run('property-descriptor-no-prototype-pollution', rule, {
17    valid: [
18      'ObjectDefineProperties({}, {})',
19      'ObjectCreate(null, {})',
20      'ObjectDefineProperties({}, { key })',
21      'ObjectCreate(null, { key })',
22      'ObjectDefineProperties({}, { ...spread })',
23      'ObjectCreate(null, { ...spread })',
24      'ObjectDefineProperties({}, { key: valueDescriptor })',
25      'ObjectCreate(null, { key: valueDescriptor })',
26      'ObjectDefineProperties({}, { key: { ...{}, __proto__: null } })',
27      'ObjectCreate(null, { key: { ...{}, __proto__: null } })',
28      'ObjectDefineProperties({}, { key: { __proto__: null } })',
29      'ObjectCreate(null, { key: { __proto__: null } })',
30      'ObjectDefineProperties({}, { key: { __proto__: null, enumerable: true } })',
31      'ObjectCreate(null, { key: { __proto__: null, enumerable: true } })',
32      'ObjectDefineProperties({}, { key: { "__proto__": null } })',
33      'ObjectCreate(null, { key: { "__proto__": null } })',
34      'ObjectDefineProperties({}, { key: { \'__proto__\': null } })',
35      'ObjectCreate(null, { key: { \'__proto__\': null } })',
36      'ObjectDefineProperty({}, "key", ObjectCreate(null))',
37      'ReflectDefineProperty({}, "key", ObjectCreate(null))',
38      'ObjectDefineProperty({}, "key", valueDescriptor)',
39      'ReflectDefineProperty({}, "key", valueDescriptor)',
40      'ObjectDefineProperty({}, "key", { __proto__: null })',
41      'ReflectDefineProperty({}, "key", { __proto__: null })',
42      'ObjectDefineProperty({}, "key", { __proto__: null, enumerable: true })',
43      'ReflectDefineProperty({}, "key", { __proto__: null, enumerable: true })',
44      'ObjectDefineProperty({}, "key", { "__proto__": null })',
45      'ReflectDefineProperty({}, "key", { "__proto__": null })',
46      'ObjectDefineProperty({}, "key", { \'__proto__\': null })',
47      'ReflectDefineProperty({}, "key", { \'__proto__\': null })',
48      'StringPrototypeReplace("some string", "some string", "some replacement")',
49      'StringPrototypeReplaceAll("some string", "some string", "some replacement")',
50      'StringPrototypeSplit("some string", "some string")',
51      'new Proxy({}, otherObject)',
52      'new Proxy({}, someFactory())',
53      'new Proxy({}, { __proto__: null })',
54      'new Proxy({}, { __proto__: null, ...{} })',
55      'async function name(){return await SafePromiseAll([])}',
56      'async function name(){const val = await SafePromiseAll([])}',
57    ],
58    invalid: [
59      {
60        code: 'ObjectDefineProperties({}, ObjectGetOwnPropertyDescriptors({}))',
61        errors: [{ message: /prototype pollution/ }],
62      },
63      {
64        code: 'ObjectCreate(null, ObjectGetOwnPropertyDescriptors({}))',
65        errors: [{ message: /prototype pollution/ }],
66      },
67      {
68        code: 'ObjectDefineProperties({}, { key: {} })',
69        errors: [{ message: /null-prototype/ }],
70      },
71      {
72        code: 'ObjectCreate(null, { key: {} })',
73        errors: [{ message: /null-prototype/ }],
74      },
75      {
76        code: 'ObjectDefineProperties({}, { key: { [void 0]: { ...{ __proto__: null } } } })',
77        errors: [{ message: /null-prototype/ }],
78      },
79      {
80        code: 'ObjectCreate(null, { key: { [void 0]: { ...{ __proto__: null } } } })',
81        errors: [{ message: /null-prototype/ }],
82      },
83      {
84        code: 'ObjectDefineProperties({}, { key: { __proto__: Object.prototype } })',
85        errors: [{ message: /null-prototype/ }],
86      },
87      {
88        code: 'ObjectCreate(null, { key: { __proto__: Object.prototype } })',
89        errors: [{ message: /null-prototype/ }],
90      },
91      {
92        code: 'ObjectDefineProperties({}, { key: { [`__proto__`]: null } })',
93        errors: [{ message: /null-prototype/ }],
94      },
95      {
96        code: 'ObjectCreate(null, { key: { [`__proto__`]: null } })',
97        errors: [{ message: /null-prototype/ }],
98      },
99      {
100        code: 'ObjectDefineProperties({}, { key: { enumerable: true } })',
101        errors: [{ message: /null-prototype/ }],
102      },
103      {
104        code: 'ObjectCreate(null, { key: { enumerable: true } })',
105        errors: [{ message: /null-prototype/ }],
106      },
107      {
108        code: 'ObjectDefineProperty({}, "key", {})',
109        errors: [{ message: /null-prototype/ }],
110      },
111      {
112        code: 'ReflectDefineProperty({}, "key", {})',
113        errors: [{ message: /null-prototype/ }],
114      },
115      {
116        code: 'ObjectDefineProperty({}, "key", ObjectGetOwnPropertyDescriptor({}, "key"))',
117        errors: [{ message: /prototype pollution/ }],
118      },
119      {
120        code: 'ReflectDefineProperty({}, "key", ObjectGetOwnPropertyDescriptor({}, "key"))',
121        errors: [{ message: /prototype pollution/ }],
122      },
123      {
124        code: 'ObjectDefineProperty({}, "key", ReflectGetOwnPropertyDescriptor({}, "key"))',
125        errors: [{ message: /prototype pollution/ }],
126      },
127      {
128        code: 'ReflectDefineProperty({}, "key", ReflectGetOwnPropertyDescriptor({}, "key"))',
129        errors: [{ message: /prototype pollution/ }],
130      },
131      {
132        code: 'ObjectDefineProperty({}, "key", { __proto__: Object.prototype })',
133        errors: [{ message: /null-prototype/ }],
134      },
135      {
136        code: 'ReflectDefineProperty({}, "key", { __proto__: Object.prototype })',
137        errors: [{ message: /null-prototype/ }],
138      },
139      {
140        code: 'ObjectDefineProperty({}, "key", { [`__proto__`]: null })',
141        errors: [{ message: /null-prototype/ }],
142      },
143      {
144        code: 'ReflectDefineProperty({}, "key", { [`__proto__`]: null })',
145        errors: [{ message: /null-prototype/ }],
146      },
147      {
148        code: 'ObjectDefineProperty({}, "key", { enumerable: true })',
149        errors: [{ message: /null-prototype/ }],
150      },
151      {
152        code: 'ReflectDefineProperty({}, "key", { enumerable: true })',
153        errors: [{ message: /null-prototype/ }],
154      },
155      {
156        code: 'RegExpPrototypeTest(/some regex/, "some string")',
157        errors: [{ message: /looks up the "exec" property/ }],
158      },
159      {
160        code: 'RegExpPrototypeSymbolMatch(/some regex/, "some string")',
161        errors: [{ message: /looks up the "exec" property/ }],
162      },
163      {
164        code: 'RegExpPrototypeSymbolMatchAll(/some regex/, "some string")',
165        errors: [{ message: /looks up the "exec" property/ }],
166      },
167      {
168        code: 'RegExpPrototypeSymbolSearch(/some regex/, "some string")',
169        errors: [{ message: /SafeStringPrototypeSearch/ }],
170      },
171      {
172        code: 'StringPrototypeMatch("some string", /some regex/)',
173        errors: [{ message: /looks up the Symbol\.match property/ }],
174      },
175      {
176        code: 'let v = StringPrototypeMatch("some string", /some regex/)',
177        errors: [{ message: /looks up the Symbol\.match property/ }],
178      },
179      {
180        code: 'let v = StringPrototypeMatch("some string", new RegExp("some regex"))',
181        errors: [{ message: /looks up the Symbol\.match property/ }],
182      },
183      {
184        code: 'StringPrototypeMatchAll("some string", /some regex/)',
185        errors: [{ message: /looks up the Symbol\.matchAll property/ }],
186      },
187      {
188        code: 'let v = StringPrototypeMatchAll("some string", new RegExp("some regex"))',
189        errors: [{ message: /looks up the Symbol\.matchAll property/ }],
190      },
191      {
192        code: 'StringPrototypeReplace("some string", /some regex/, "some replacement")',
193        errors: [{ message: /looks up the Symbol\.replace property/ }],
194      },
195      {
196        code: 'StringPrototypeReplace("some string", new RegExp("some regex"), "some replacement")',
197        errors: [{ message: /looks up the Symbol\.replace property/ }],
198      },
199      {
200        code: 'StringPrototypeReplaceAll("some string", /some regex/, "some replacement")',
201        errors: [{ message: /looks up the Symbol\.replace property/ }],
202      },
203      {
204        code: 'StringPrototypeReplaceAll("some string", new RegExp("some regex"), "some replacement")',
205        errors: [{ message: /looks up the Symbol\.replace property/ }],
206      },
207      {
208        code: 'StringPrototypeSearch("some string", /some regex/)',
209        errors: [{ message: /SafeStringPrototypeSearch/ }],
210      },
211      {
212        code: 'StringPrototypeSplit("some string", /some regex/)',
213        errors: [{ message: /looks up the Symbol\.split property/ }],
214      },
215      {
216        code: 'new Proxy({}, {})',
217        errors: [{ message: /null-prototype/ }]
218      },
219      {
220        code: 'new Proxy({}, { [`__proto__`]: null })',
221        errors: [{ message: /null-prototype/ }]
222      },
223      {
224        code: 'new Proxy({}, { __proto__: Object.prototype })',
225        errors: [{ message: /null-prototype/ }]
226      },
227      {
228        code: 'new Proxy({}, { ...{ __proto__: null } })',
229        errors: [{ message: /null-prototype/ }]
230      },
231      {
232        code: 'PromisePrototypeCatch(promise, ()=>{})',
233        errors: [{ message: /\bPromisePrototypeThen\b/ }]
234      },
235      {
236        code: 'PromiseAll([])',
237        errors: [{ message: /\bSafePromiseAll\b/ }]
238      },
239      {
240        code: 'async function fn(){await SafePromiseAll([])}',
241        errors: [{ message: /\bSafePromiseAllReturnVoid\b/ }]
242      },
243      {
244        code: 'async function fn(){await SafePromiseAllSettled([])}',
245        errors: [{ message: /\bSafePromiseAllSettledReturnVoid\b/ }]
246      },
247      {
248        code: 'PromiseAllSettled([])',
249        errors: [{ message: /\bSafePromiseAllSettled\b/ }]
250      },
251      {
252        code: 'PromiseAny([])',
253        errors: [{ message: /\bSafePromiseAny\b/ }]
254      },
255      {
256        code: 'PromiseRace([])',
257        errors: [{ message: /\bSafePromiseRace\b/ }]
258      },
259      {
260        code: 'ArrayPrototypeConcat([])',
261        errors: [{ message: /\bisConcatSpreadable\b/ }]
262      },
263    ]
264  });
265