Buckets:
| # secure-json-parse | |
| [](https://github.com/fastify/secure-json-parse/actions/workflows/ci.yml) | |
| [](https://www.npmjs.com/package/secure-json-parse) | |
| [](https://github.com/neostandard/neostandard) | |
| `JSON.parse()` drop-in replacement with prototype poisoning protection. | |
| ## Introduction | |
| Consider this: | |
| ```js | |
| > const a = '{"__proto__":{ "b":5}}'; | |
| '{"__proto__":{ "b":5}}' | |
| > const b = JSON.parse(a); | |
| { __proto__: { b: 5 } } | |
| > b.b; | |
| undefined | |
| > const c = Object.assign({}, b); | |
| {} | |
| > c.b | |
| 5 | |
| ``` | |
| The problem is that `JSON.parse()` retains the `__proto__` property as a plain object key. By | |
| itself, this is not a security issue. However, as soon as that object is assigned to another or | |
| iterated on and values copied, the `__proto__` property leaks and becomes the object's prototype. | |
| ## Install | |
| ``` | |
| npm i secure-json-parse | |
| ``` | |
| ## Usage | |
| Pass the option object as a second (or third) parameter for configuring the action to take in case of a bad JSON, if nothing is configured, the default is to throw a `SyntaxError`.<br/> | |
| You can choose which action to perform in case `__proto__` is present, and in case `constructor.prototype` is present. | |
| ```js | |
| const sjson = require('secure-json-parse') | |
| const goodJson = '{ "a": 5, "b": 6 }' | |
| const badJson = '{ "a": 5, "b": 6, "__proto__": { "x": 7 }, "constructor": {"prototype": {"bar": "baz"} } }' | |
| console.log(JSON.parse(goodJson), sjson.parse(goodJson, undefined, { protoAction: 'remove', constructorAction: 'remove' })) | |
| console.log(JSON.parse(badJson), sjson.parse(badJson, undefined, { protoAction: 'remove', constructorAction: 'remove' })) | |
| ``` | |
| ## API | |
| ### `sjson.parse(text, [reviver], [options])` | |
| Parses a given JSON-formatted text into an object where: | |
| - `text` - the JSON text string. | |
| - `reviver` - the `JSON.parse()` optional `reviver` argument. | |
| - `options` - optional configuration object where: | |
| - `protoAction` - optional string with one of: | |
| - `'error'` - throw a `SyntaxError` when a `__proto__` key is found. This is the default value. | |
| - `'remove'` - deletes any `__proto__` keys from the result object. | |
| - `'ignore'` - skips all validation (same as calling `JSON.parse()` directly). | |
| - `constructorAction` - optional string with one of: | |
| - `'error'` - throw a `SyntaxError` when a `constructor.prototype` key is found. This is the default value. | |
| - `'remove'` - deletes any `constructor` keys from the result object. | |
| - `'ignore'` - skips all validation (same as calling `JSON.parse()` directly). | |
| - `safe` - optional boolean: | |
| - `true` - returns `null` instead of throwing when a forbidden prototype property is found. | |
| - `false` - default behavior (throws or removes based on `protoAction`/`constructorAction`). | |
| ### `sjson.scan(obj, [options])` | |
| Scans a given object for prototype properties where: | |
| - `obj` - the object being scanned. | |
| - `options` - optional configuration object where: | |
| - `protoAction` - optional string with one of: | |
| - `'error'` - throw a `SyntaxError` when a `__proto__` key is found. This is the default value. | |
| - `'remove'` - deletes any `__proto__` keys from the input `obj`. | |
| - `constructorAction` - optional string with one of: | |
| - `'error'` - throw a `SyntaxError` when a `constructor.prototype` key is found. This is the default value. | |
| - `'remove'` - deletes any `constructor` keys from the input `obj`. | |
| - `safe` - optional boolean: | |
| - `true` - returns `null` instead of throwing when a forbidden prototype property is found. | |
| - `false` - default behavior (throws or removes based on `protoAction`/`constructorAction`). | |
| ## Benchmarks | |
| Machine: 2,7 GHz Quad-Core Intel Core i7 | |
| ``` | |
| v14.8.0 | |
| > node ignore.js | |
| JSON.parse x 679,376 ops/sec ±1.15% (84 runs sampled) | |
| secure-json-parse x 649,605 ops/sec ±0.58% (87 runs sampled) | |
| reviver x 244,414 ops/sec ±1.05% (88 runs sampled) | |
| Fastest is JSON.parse | |
| > node no__proto__.js | |
| JSON.parse x 652,190 ops/sec ±0.67% (86 runs sampled) | |
| secure-json-parse x 589,785 ops/sec ±1.01% (88 runs sampled) | |
| reviver x 218,075 ops/sec ±1.58% (87 runs sampled) | |
| Fastest is JSON.parse | |
| > node remove.js | |
| JSON.parse x 683,527 ops/sec ±0.62% (88 runs sampled) | |
| secure-json-parse x 316,926 ops/sec ±0.63% (87 runs sampled) | |
| reviver x 214,167 ops/sec ±0.63% (86 runs sampled) | |
| Fastest is JSON.parse | |
| > node throw.js | |
| JSON.parse x 682,548 ops/sec ±0.60% (88 runs sampled) | |
| JSON.parse error x 170,716 ops/sec ±0.93% (87 runs sampled) | |
| secure-json-parse x 104,483 ops/sec ±0.62% (87 runs sampled) | |
| reviver x 114,197 ops/sec ±0.63% (87 runs sampled) | |
| Fastest is JSON.parse | |
| ``` | |
| ## Acknowledgments | |
| This project has been forked from [hapijs/bourne](https://github.com/hapijs/bourne). | |
| All credit before commit [4690682](https://github.com/hapijs/bourne/commit/4690682c6cdaa06590da7b2485d5df91c09da889) goes to the hapijs/bourne project contributors. | |
| After, the project will be maintained by the Fastify team. | |
| ## License | |
| Licensed under [BSD-3-Clause](./LICENSE). | |
Xet Storage Details
- Size:
- 5.27 kB
- Xet hash:
- 4ca21b7739e175cdc1f57001a7a992c8e64c707d912801c2b5e63d127d0e5be6
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.