{ }JSON Workshop/Formatter & Validator
Security••8 min read

JSON Security Best Practices: Preventing XSS, Injection, and Payload Attacks

A practical guide to safely accept, validate, store, and render JSON in APIs and browser applications.

Written by JSON Workshop Team

Introduction

JSON is data, not executable code. The security risk usually appears at the boundaries: accepting an untrusted request, storing it, displaying a value in HTML, or using it to make an authorization decision. Treat every value from an external JSON document as untrusted until it has been checked for the operation you intend to perform.

Parsing a document with JSON.parse() is safer than executing it, yet a successfully parsed value can still be unsafe to render or pass to another system. This guide focuses on server-side APIs, but the same principles apply in browser applications.

1. Never use eval() to parse JSON

Legacy JavaScript applications sometimes used eval(). Never use it for request data: it evaluates JavaScript rather than just reading JSON.

// Dangerous: runs arbitrary JavaScript.
const value = eval('(' + userInput + ')');

// Safe parsing for JSON syntax.
const value = JSON.parse(userInput);

Use a standard parser in every language. It rejects malformed input instead of attempting to interpret it as code.

2. Set a realistic payload limit

An unbounded request body can consume memory or tie up a process before your application reaches validation. Set a limit before parsing, based on the largest legitimate request for that endpoint. Return a clear 413 Payload Too Large response when the limit is exceeded.

For example, an Express API can set a limit at middleware level:

app.use(express.json({ limit: '1mb' }));

File imports often need different handling: use a separate endpoint, enforce timeouts, and avoid loading an unexpectedly large document into memory all at once.

3. Validate the shape after parsing

Valid JSON is not necessarily valid application data. Parsing checks punctuation and JSON data types; it does not prove that a role, price, or userId is allowed. Validate expected fields, types, ranges, and nested objects at the API boundary.

For a registration endpoint, this might mean accepting a non-empty email string and a display name with a maximum length, while rejecting unexpected properties. JSON Schema or a server-side validation library can make these rules explicit and reusable.

4. Keep authorization separate from the payload

Never trust identity, ownership, or permissions simply because a client sends them in JSON. A request body such as { "role": "admin" } must not grant a role. Derive identity from an authenticated session or token, then check permissions against server-controlled data.

Apply the same rule to object identifiers. Before returning or changing a record, verify that the signed-in user is allowed to access the identifier in the request.

5. Render strings as text, not HTML

An API response may legitimately contain text that looks like markup. If you insert that string with an HTML-interpreting API, it can become an XSS vulnerability. Prefer text-rendering APIs such as textContent. Only accept HTML where the product truly needs it, and sanitize it with a maintained, context-appropriate library.

Escaping belongs at the output point because HTML, URLs, JavaScript, and database queries each have different rules. A single “clean JSON” step cannot make every downstream use safe.

6. Avoid unsafe object merging

When merging untrusted objects, special keys such as __proto__, constructor, and prototype can cause problems in some JavaScript libraries and older patterns. Avoid broad deep-merge helpers for request data. Pick the fields you expect into a fresh object and validate them.

const input = JSON.parse(requestBody);
const profile = {
  displayName: input.displayName,
  timezone: input.timezone,
};

This pattern prevents accidentally accepting properties that were never part of your public API.

7. Log carefully

Logs help diagnose malformed requests, but raw JSON may contain passwords, access tokens, addresses, or other personal data. Redact sensitive fields before logging and use a retention period. When reporting a parser error to a client, keep the response useful without echoing the entire payload back.

A practical request-handling checklist

  • Set a content-type policy and a realistic request-size limit.
  • Parse with a standard JSON parser; never execute the body.
  • Validate the schema, including maximum lengths and allowed values.
  • Authorize the action using server-controlled identity and data.
  • Escape or sanitize values for the exact output context.
  • Redact secrets from logs and error reports.
  • Test oversized, malformed, and unexpected payloads.

For secure client-side JSON processing where no JSON payload leaves your device, use the JSON Workshop formatter and validator.

Need to format or validate JSON?

Try our 100% private, client-side JSON Formatter & Validator tool.

Open JSON Formatter →