1 | ;
|
2 | // Copyright IBM Corp. and LoopBack contributors 2019. All Rights Reserved.
|
3 | // Node module: @loopback/rest
|
4 | // This file is licensed under the MIT License.
|
5 | // License text available at https://opensource.org/licenses/MIT
|
6 | Object.defineProperty(exports, "__esModule", { value: true });
|
7 | exports.parseJson = exports.sanitizeJsonParse = void 0;
|
8 | /* eslint-disable @typescript-eslint/no-explicit-any */
|
9 | // These utilities are introduced to mitigate the prototype pollution issue
|
10 | // with `JSON.parse`.
|
11 | // See https://hueniverse.com/a-tale-of-prototype-poisoning-2610fa170061
|
12 | //
|
13 | // The [bourne](https://github.com/hapijs/bourne) module provides a drop-in
|
14 | // replacement for `JSON.parse` but we need to instruct `body-parser` to honor
|
15 | // a `reviver` function.
|
16 | const isMatched = (key, pattern) => pattern === key || key.indexOf(`${pattern}.`) === 0;
|
17 | /**
|
18 | * Factory to create a reviver function for `JSON.parse` to sanitize keys
|
19 | * @param reviver - Reviver function
|
20 | * @param prohibitedKeys - An array of keys to be rejected
|
21 | */
|
22 | function sanitizeJsonParse(reviver, prohibitedKeys) {
|
23 | return (key, value) => {
|
24 | if (key === '__proto__') {
|
25 | // Reject `__proto__`
|
26 | throw new Error(`JSON string cannot contain "${key}" key.`);
|
27 | }
|
28 | if (key === 'constructor' &&
|
29 | value != null &&
|
30 | Object.keys(value).some(k => isMatched(k, 'prototype'))) {
|
31 | // Reject `constructor/prototype.*`
|
32 | throw new Error(`JSON string cannot contain "constructor.prototype" key.`);
|
33 | }
|
34 | if (prohibitedKeys === null || prohibitedKeys === void 0 ? void 0 : prohibitedKeys.some(pattern => isMatched(key, pattern))) {
|
35 | throw new Error(`JSON string cannot contain "${key}" key.`);
|
36 | }
|
37 | if (reviver) {
|
38 | return reviver(key, value);
|
39 | }
|
40 | else {
|
41 | return value;
|
42 | }
|
43 | };
|
44 | }
|
45 | exports.sanitizeJsonParse = sanitizeJsonParse;
|
46 | /**
|
47 | * Parse a json string that rejects prohibited keys
|
48 | * @param text - JSON string
|
49 | * @param reviver - Optional reviver function for `JSON.parse`
|
50 | * @param prohibitedKeys - An array of keys to be rejected
|
51 | */
|
52 | function parseJson(text, reviver, prohibitedKeys) {
|
53 | prohibitedKeys = [
|
54 | '__proto__',
|
55 | 'constructor.prototype',
|
56 | ...(prohibitedKeys !== null && prohibitedKeys !== void 0 ? prohibitedKeys : []),
|
57 | ];
|
58 | return JSON.parse(text, sanitizeJsonParse(reviver, prohibitedKeys));
|
59 | }
|
60 | exports.parseJson = parseJson;
|
61 | //# sourceMappingURL=parse-json.js.map |
\ | No newline at end of file |