JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 8690427
  • Score
    100M100P100Q223075F
  • License BSD-3-Clause

JSON parse with prototype poisoning protection

Package Exports

  • secure-json-parse

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (secure-json-parse) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

secure-json-parse

Build Status js-standard-style

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.

Install

npm install 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.
You can choose which action to perform in case __proto__ is present, and in case constructor is present.

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, { protoAction: 'remove', constructorAction: 'remove' }))
console.log(JSON.parse(badJson), sjson.parse(badJson, { 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 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 key is found. This is the default value.
      • 'remove' - deletes any constructor keys from the input obj.

Acknowledgements

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.

License

Licensed under BSD-3-Clause.