JSON Security Best Practices - Protecting Your Applications
2026-01-30#JSON#Security#API#Best Practices
JSON handling introduces security risks if not done carefully. This guide covers essential security practices for protecting your applications.
Injection Attacks
Preventing JavaScript Injection
Never pass untrusted JSON to eval():
// DANGEROUS - Never do this
const data = eval('(' + userInput + ')'); // XSS vulnerability
// SAFE - Use JSON.parse
const data = JSON.parse(userInput); // Only parses valid JSON
Prototype Pollution Prevention
Protect against prototype pollution:
// Dangerous - allows prototype modification
function merge(target, source) {
for (const key in source) {
target[key] = source[key];
}
}
// Safe - block dangerous keys
function safeMerge(target, source) {
const dangerous = ['__proto__', 'constructor', 'prototype'];
for (const key in source) {
if (dangerous.includes(key)) continue;
if (key.startsWith('__')) continue;
target[key] = source[key];
}
}
JSON String Injection
Validate input to prevent injection:
function sanitizeJsonInput(input) {
// Remove control characters except newlines and tabs
return input.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, '');
}
// Validate structure before parsing
function validateStructure(jsonString) {
if (/^\s*\{\s*"__proto__"/m.test(jsonString)) {
throw new Error('Potentially malicious JSON detected');
}
if (/^\s*\{\s*"constructor"/m.test(jsonString)) {
throw new Error('Potentially malicious JSON detected');
}
}
DoS Prevention
Depth Limits
Prevent deeply nested objects:
const MAX_DEPTH = 100;
function parseWithDepthLimit(jsonString, maxDepth = MAX_DEPTH) {
let depth = 0;
function parse(value) {
if (depth > maxDepth) {
throw new Error('Maximum nesting depth exceeded');
}
if (typeof value === 'object' && value !== null) {
depth++;
for (const key in value) {
await parse(value[key]);
}
depth--;
}
}
const data = JSON.parse(jsonString);
parse(data);
return data;
}
Size Limits
Restrict JSON size:
const MAX_SIZE = 10 * 1024 * 1024; // 10MB
function validateSize(req, res, next) {
const size = parseInt(req.headers['content-length'], 10);
if (size > MAX_SIZE) {
return res.status(413).json({
error: 'Payload Too Large',
message: 'JSON payload exceeds maximum size'
});
}
next();
}
Item Count Limits
const MAX_ITEMS = 10000;
function validateItemCount(jsonData) {
function countItems(value) {
if (Array.isArray(value)) {
if (value.length > MAX_ITEMS) {
throw new Error(`Array exceeds ${MAX_ITEMS} items`);
}
return value.reduce((sum, item) => sum + countItems(item), value.length);
}
if (typeof value === 'object' && value !== null) {
return Object.values(value).reduce(
(sum, v) => sum + countItems(v), 1
);
}
return 1;
}
return countItems(jsonData);
}
Sensitive Data Handling
Preventing Information Leakage
function sanitizeResponse(data) {
const sensitiveFields = ['password', 'secret', 'token', 'apiKey'];
function removeSensitive(obj) {
if (typeof obj !== 'object' || obj === null) return obj;
const result = Array.isArray(obj) ? [...obj] : { ...obj };
for (const key of Object.keys(result)) {
if (sensitiveFields.some(field => key.toLowerCase().includes(field))) {
delete result[key];
} else if (typeof result[key] === 'object') {
result[key] = removeSensitive(result[key]);
}
}
return result;
}
return removeSensitive(data);
}
Logging Redaction
function redactSensitive(data) {
const patterns = [
/credit\s*card/i,
/password/i,
/secret/i,
/token/i,
/api\s*key/i
];
function redact(value) {
if (typeof value === 'string') {
return patterns.some(p => p.test(value))
? '[REDACTED]'
: value;
}
if (typeof value === 'object' && value !== null) {
const result = Array.isArray(value) ? [...value] : { ...value };
for (const key in result) {
if (patterns.some(p => p.test(key))) {
result[key] = '[REDACTED]';
} else {
result[key] = redact(result[key]);
}
}
return result;
}
return value;
}
return redact(data);
}
CORS and CSP
Proper CORS Configuration
const allowedOrigins = [
'https://example.com',
'https://api.example.com'
];
app.use((req, res, next) => {
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
}
next();
});
Content Security Policy
app.use((req, res) => {
res.setHeader('Content-Security-Policy',
"default-src 'self'; " +
"script-src 'self'; " +
"style-src 'self' 'unsafe-inline'; " +
"img-src 'self' data:; " +
"connect-src 'self' https://api.example.com"
);
});
Rate Limiting
const rateLimit = require('express-rate-limit');
const jsonParserLimiter = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 30, // 30 requests per minute
message: {
error: 'Too Many Requests',
message: 'JSON parsing rate limit exceeded'
},
keyGenerator: (req) => req.ip,
skip: (req) => req.method === 'GET'
});
app.post('/api/parse', jsonParserLimiter, parseHandler);
HTTPS Enforcement
app.use((req, res, next) => {
if (req.headers['x-forwarded-proto'] !== 'https') {
return res.redirect(301, `https://${req.hostname }
next();
});
##}${req.url}`); Input Validation
Schema Validation
const Ajv = require('ajv');
const ajv = new Ajv({ allErrors: true });
const userSchema = {
type: 'object',
properties: {
email: { type: 'string', format: 'email' },
age: { type: 'integer', minimum: 0, maximum: 150 }
},
required: ['email'],
additionalProperties: false
};
const validate = ajv.compile(userSchema);
function validateUser(req, res, next) {
const valid = validate(req.body);
if (!valid) {
return res.status(400).json({
error: 'Validation Failed',
details: validate.errors
});
}
next();
}
Summary
Secure JSON handling requires: preventing injection attacks, limiting depth/size, protecting sensitive data, configuring CORS/CSP, rate limiting, using HTTPS, and validating all input.
Related articles
Working with Large JSON Files - A Practical Guide
Techniques and tools for handling JSON files that exceed memory limits or browser constraints.
JSON vs XML - Choosing the Right Format for Your Use Case
A comprehensive comparison of JSON and XML to help you make informed format decisions.
JSON Tools Ecosystem - A Comprehensive Overview
Explore the best tools, libraries, and utilities for working with JSON across different platforms and use cases.
Understanding JSON Schema - A Complete Guide
Learn how to define and validate JSON structure with JSON Schema, from basics to advanced features.
JSON Performance Optimization Techniques
Speed up JSON parsing, serialization, and processing with these proven optimization strategies.
JSON in Modern Web Development - 2026 Trends and Best Practices
Explore current trends, emerging patterns, and best practices for JSON in modern web development.