Need help with your JSON?
Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool
JSON Injection Attacks: How Formatters Help Prevent Them
JSON injection usually means one thing: untrusted input changes the meaning of data before your application finishes handling it. Sometimes that means unsafe parsing with eval(). More often today, it means developers build JSON with string concatenation, accept raw JSON query fragments from clients, or embed serialized JSON into HTML without the right output encoding.
A JSON formatter helps, but only in specific ways. It enforces valid syntax, escapes string content when you serialize data, and makes suspicious structure easier to spot during review. It does notdecide whether fields are allowed, whether a parsed object is safe to send into a database query, or whether valid JSON is being inserted into a dangerous HTML or JavaScript context.
What Searchers Usually Mean by "JSON Injection"
If someone searches for json injection, they are usually dealing with one of these patterns:
- Parsing data as code: using
eval(),Function(), or similar dynamic execution on untrusted text. - Breaking JSON structure during construction: concatenating user input into a JSON string so an attacker can close a string early or add new properties.
- Passing parsed JSON straight into downstream APIs: for example, treating a client-supplied object as a MongoDB filter or update document.
- Embedding JSON into HTML unsafely: serializing valid JSON and then dropping it into a
<script>tag or inline script without context-aware escaping.
The common thread is that the attacker is not just sending data. They are influencing structure, behavior, or interpretation.
Danger #1: Parsing JSON with Code Execution
This is the classic case. MDN explicitly warns that eval() is dangerous and can open the door to arbitrary code execution and injection attacks. If the input is not strict JSON but is still valid JavaScript, eval() will run it.
Unsafe Example: eval() Accepts JavaScript, Not Just JSON
// Assume this string comes from a request body
const userInput =
'{"name":"Attacker","run":(function(){alert("owned");return true;})()}';
// Dangerous: eval executes JavaScript expressions
const data = eval("(" + userInput + ")");
console.log(data.name); // "Attacker"
// The injected function runs during parsing
eval() turns a parsing problem into a code-execution problem. That is far worse than a normal validation bug.
The safe alternative is JSON.parse(). It is a parser, not a JavaScript interpreter. It accepts only valid JSON values, so functions, comments, trailing commas, and bare expressions are rejected with a SyntaxError instead of being executed.
Safe Example: JSON.parse() Rejects Non-JSON Input
const userInput =
'{"name":"Attacker","run":(function(){alert("owned");return true;})()}';
try {
const data = JSON.parse(userInput);
console.log(data);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
console.error("Invalid JSON:", message);
}
// Result: parsing fails and the injected code never runs
A strict parser blocks this class of attack because non-JSON tokens are treated as invalid input, not as executable code.
Danger #2: Building JSON Strings by Hand
A more common modern bug is not unsafe parsing. It is unsafe construction. If you build JSON with string concatenation, a user can inject quotes, commas, or extra properties and still end up with perfectly valid JSON that means something different from what you intended.
Unsafe Example: User Input Changes the JSON Structure
const name = req.body.name;
// Dangerous: hand-built JSON string
const payload = '{ "name": "' + name + '", "role": "user" }';
const data = JSON.parse(payload);
// If name is:
// Alice", "role": "admin
//
// payload becomes:
// { "name": "Alice", "role": "admin", "role": "user" }
//
// Depending on the parser and downstream code, duplicate keys can create
// surprising results and hide what the attacker changed.
The fix is simple: build native objects and let the formatter or serializer handle escaping for you. In JavaScript, that means object literals plus JSON.stringify().
Safe Example: Build Objects, Then Serialize
const data = {
name: String(req.body.name),
role: "user",
};
const payload = JSON.stringify(data);
// Quotes, backslashes, and control characters inside name are escaped safely
A formatter helps most when it is generating JSON for you. Manual string building is where structure injection usually starts.
Danger #3: Valid JSON That Becomes a Dangerous Query
This is the limitation many articles skip: perfectly valid JSON can still be dangerous after it has been parsed. OWASP's NoSQL security guidance recommends strict input validation, allowlists, and safe driver APIs for exactly this reason.
Unsafe Example: Accepting a Raw Filter Object from the Client
// Client controls the entire filter
const filter = JSON.parse(req.body.filter);
const user = await db.collection("users").findOne(filter);
// Attacker sends:
// { "email": { "$ne": null } }
//
// Or tries operator keys you never intended to expose.
JSON.parse() did its job here. The JSON is valid. The problem is that your application accepted attacker-controlled structure and handed it to a query engine. A formatter cannot decide whether $ne, $regex, or other special operator keys belong in your API. That is an application-level validation problem.
The safer pattern is to accept specific fields, convert them to expected primitive types, and build the query object yourself.
Safer Pattern: Build the Query Server-Side
const email = String(req.body.email);
const filter = { email };
const user = await db.collection("users").findOne(filter);
// If advanced filtering is a real product feature, define an allowlist
// for fields, operators, and value types instead of accepting raw JSON.
Danger #4: Embedding JSON into HTML or a Script Tag
Even correctly serialized JSON can become an XSS problem if you place it into HTML without the right encoding for that output context. OWASP's XSS prevention guidance makes the broader rule clear: escaping depends on where the data is rendered.
Unsafe Example: JSON Is Valid, but HTML Context Is Not Safe
const state = JSON.stringify(profile);
return `<script>window.__STATE__ = ${state}</script>`;
// If profile contains "</script><script>alert(1)</script>"
// the browser can break out of the original script block.
A practical fix is to use the framework's built-in serializer when available, or escape dangerous characters before embedding the JSON into HTML.
Safer Pattern: Serialize, Then Escape for HTML
const state = JSON.stringify(profile).replace(/</g, "\u003c");
return `<script>window.__STATE__ = ${state}</script>`;
// JSON formatting helps create valid JSON.
// HTML-aware escaping helps keep that JSON inside the script block.
How Formatters Actually Help
A JSON formatter is useful security tooling when you use it for the right job:
- Strict parsing: it rejects invalid JSON instead of evaluating it as code.
- Safe serialization: it escapes quotes, backslashes, and control characters correctly when generating JSON.
- Normalization: pretty-printing makes unexpected nesting, duplicate-looking fields, and operator-shaped keys easier to review.
- Debugging: if a payload only works when hand-built, that is a sign your application logic is relying on broken JSON rather than valid data handling.
What Formatters Cannot Do for You
A formatter is a guardrail, not a complete injection defense. You still need application-level controls:
- Schema validation: verify required keys, data types, allowed enums, and nested structure with JSON Schema, Ajv, Zod, Joi, or similar tooling.
- Allowlists: decide which fields and operators are permitted instead of trusting arbitrary parsed objects.
- Context-aware output encoding: valid JSON still needs HTML or JavaScript-safe handling when rendered into a page.
- Resource limits: deeply nested or oversized JSON can still cause memory and CPU problems even when parsing is syntactically safe.
Practical Checklist
- Parse untrusted input with
JSON.parse(), nevereval()ornew Function(). - Build data as native objects and serialize with
JSON.stringify()instead of concatenating strings. - Validate the parsed result against an expected schema before using it.
- Do not accept raw query or update JSON from clients unless you explicitly constrain it.
- When embedding serialized JSON into HTML, apply output encoding for the HTML or script context too.
- Set request size limits and reject unusually deep or complex payloads early.
Conclusion
The short version is simple: use a formatter to keep JSON valid, but do not mistake valid JSON for safe behavior. JSON.parse() stops code execution tricks. JSON.stringify() stops many string-construction bugs. Neither one can tell whether a field should exist, whether a query operator is acceptable, or whether JSON is being injected into a dangerous browser context.
For real-world protection, combine strict parsing, safe serialization, schema validation, and context-aware output encoding. That is the difference between merely accepting JSON and handling it safely.
Need help with your JSON?
Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool