What is @hapi/bourne?
@hapi/bourne is a JSON parser that is designed to be secure by preventing prototype pollution attacks. It is a part of the hapi ecosystem and focuses on safely parsing JSON strings.
What are @hapi/bourne's main functionalities?
Safe JSON Parsing
This feature allows you to safely parse JSON strings into JavaScript objects, ensuring that the parsed object does not contain any prototype pollution.
const Bourne = require('@hapi/bourne');
const jsonString = '{"key":"value"}';
const parsedObject = Bourne.parse(jsonString);
console.log(parsedObject); // { key: 'value' }
Handling Malicious JSON
This feature demonstrates how @hapi/bourne handles potentially malicious JSON strings that attempt to pollute the prototype. The parser ensures that such attempts are neutralized.
const Bourne = require('@hapi/bourne');
const maliciousJsonString = '{"__proto__":{"polluted":"yes"}}';
const parsedObject = Bourne.parse(maliciousJsonString);
console.log(parsedObject.polluted); // undefined
Other packages similar to @hapi/bourne
json5
JSON5 is a JSON parser that allows for more human-friendly JSON. It supports comments, trailing commas, and more. Unlike @hapi/bourne, JSON5 focuses on extending the JSON syntax rather than security.
secure-json-parse
secure-json-parse is another package that focuses on safely parsing JSON strings to prevent prototype pollution attacks. It is similar to @hapi/bourne in its security focus but offers additional features like revivers and custom error handling.
fast-json-parse
fast-json-parse is a high-performance JSON parser that aims to be faster than the native JSON.parse method. While it does not focus on security like @hapi/bourne, it is useful for performance-critical applications.
Bourne. JSON Bourne.
JSON.parse()
drop-in replacement with prototype poisoning protection
Introduction
Consider this:
> 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.
API
Bourne.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).
Bourne.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
.