Gathering detailed insights and metrics for secure-json-parse
Gathering detailed insights and metrics for secure-json-parse
Gathering detailed insights and metrics for secure-json-parse
Gathering detailed insights and metrics for secure-json-parse
JSON.parse() drop-in replacement with prototype poisoning protection
npm install secure-json-parse
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
225 Stars
172 Commits
17 Forks
13 Watching
2 Branches
32 Contributors
Updated on 18 Nov 2024
JavaScript (95.5%)
TypeScript (4.5%)
Cumulative downloads
Total Downloads
Last day
2.6%
1,171,791
Compared to previous day
Last week
3.3%
6,055,706
Compared to previous week
Last month
14.3%
24,246,073
Compared to previous month
Last year
56.1%
227,002,853
Compared to previous year
JSON.parse()
drop-in replacement with prototype poisoning protection.
Consider this:
1> const a = '{"__proto__":{ "b":5}}'; 2'{"__proto__":{ "b":5}}' 3 4> const b = JSON.parse(a); 5{ __proto__: { b: 5 } } 6 7> b.b; 8undefined 9 10> const c = Object.assign({}, b); 11{} 12 13> c.b 145
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.
npm i secure-json-parse
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
.
You can choose which action to perform in case __proto__
is present, and in case constructor.prototype
is present.
1const sjson = require('secure-json-parse') 2 3const goodJson = '{ "a": 5, "b": 6 }' 4const badJson = '{ "a": 5, "b": 6, "__proto__": { "x": 7 }, "constructor": {"prototype": {"bar": "baz"} } }' 5 6console.log(JSON.parse(goodJson), sjson.parse(goodJson, undefined, { protoAction: 'remove', constructorAction: 'remove' })) 7console.log(JSON.parse(badJson), sjson.parse(badJson, undefined, { protoAction: 'remove', constructorAction: 'remove' }))
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).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
.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
This project has been forked from hapijs/bourne. All the credits before the commit 4690682 goes to the hapijs/bourne project contributors. After, the project will be maintained by the Fastify team.
Licensed under BSD-3-Clause.
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
no dangerous workflow patterns detected
Reason
0 existing vulnerabilities detected
Reason
security policy file detected
Details
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
license file detected
Details
Reason
SAST tool is not run on all commits -- score normalized to 5
Details
Reason
4 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 4
Reason
Found 6/18 approved changesets -- score normalized to 3
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Score
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More