# secure-json-parse

> JSON parse with prototype poisoning protection

Latest version **4.1.0** (published 2025-10-05) · BSD-3-Clause license · 0 weekly downloads

## Install

```sh
npm install secure-json-parse
pnpm add secure-json-parse
yarn add secure-json-parse
bun add secure-json-parse
```

## Health

**Score 60/100 (C)** — status: stable.

Positive: has types; no vulnerabilities; high maintenance score; high quality score.

Warnings: low downloads; no esm support.

## Facts

| | |
|---|---|
| Version | 4.1.0 |
| Published | 2025-10-05 |
| First published | 2019-04-29 |
| Weekly downloads | 0 |
| License | BSD-3-Clause |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 49.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 251 |
| Author | Eran Hammer |
| Maintainers | jsumners, delvedor, matteo.collina, eomm, climba03003, zekth, gurgunday, ivan-tymoshenko, simoneb, fdawgs, metcoder95 |
| Keywords | JSON, parse, safe, security, prototype, pollution |

## Links

- npm: https://www.npmjs.com/package/secure-json-parse
- Repository: https://github.com/fastify/secure-json-parse
- Homepage: https://github.com/fastify/secure-json-parse#readme
- Issues: https://github.com/fastify/secure-json-parse/issues
- Funding: https://github.com/sponsors/fastify
- npm.io page: https://npm.io/package/secure-json-parse

## Alternatives

- [@mapbox/jsonlint-lines-primitives](https://npm.io/package/@mapbox/jsonlint-lines-primitives.md) — 5.3M weekly downloads
- [reftools](https://npm.io/package/reftools.md) — 3.5M weekly downloads
- [@hey-api/openapi-ts](https://npm.io/package/@hey-api/openapi-ts.md) — 3.5M weekly downloads
- [@mapbox/geojson-rewind](https://npm.io/package/@mapbox/geojson-rewind.md) — 2.4M weekly downloads
- [turbo-stream](https://npm.io/package/turbo-stream.md) — 1.7M weekly downloads

## Recent versions

- 4.1.0 (latest) — 2025-10-05
- 3.0.0 (next) — 2024-09-03
- 4.0.0 — 2025-03-09
- 3.0.2 — 2025-01-03
- 3.0.1 — 2024-11-18
- 2.7.0 — 2023-01-10
- 2.6.0 — 2022-12-05
- 2.5.0 — 2022-07-29
- 2.4.0 — 2021-04-06
- 2.3.2 — 2021-03-15
- 2.3.1 — 2021-02-17
- 2.3.0 — 2021-01-26
- 2.2.0 — 2021-01-11
- 2.1.0 — 2020-01-15
- 2.0.0 — 2019-10-23
- … 2 more at https://npm.io/package/secure-json-parse/versions

## README

# secure-json-parse

[![CI](https://github.com/fastify/secure-json-parse/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/fastify/secure-json-parse/actions/workflows/ci.yml)
[![NPM version](https://img.shields.io/npm/v/secure-json-parse.svg?style=flat)](https://www.npmjs.com/package/secure-json-parse)
[![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-brightgreen?style=flat)](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).

---
_Source: https://npm.io/package/secure-json-parse · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
