JSON Security & Data Protection
Master JSON security best practices and protect your applications from vulnerabilities. Learn to prevent XSS, injection attacks, data leakage, and implement secure JSON handling.
Why JSON Security Matters
JSON is everywhere in modern web applications—APIs, configuration files, data storage, and communication between services. Poor JSON security can lead to data breaches, XSS attacks, injection vulnerabilities, and unauthorized access.
⚠️ Critical Security Principle:
Never trust JSON data from external sources. Always validate, sanitize, and verify data integrity before processing or displaying it.
Common JSON Security Vulnerabilities
1. XSS (Cross-Site Scripting)
Malicious scripts injected through JSON that execute in the browser.
❌ Vulnerable:
const data = JSON.parse(input);
document.innerHTML = data.message;
// If message contains <script>...
// it will execute! ✓ Secure:
const data = JSON.parse(input);
const div = document.createElement('div');
div.textContent = data.message;
// Scripts won't execute 2. JSON Injection
Manipulating JSON structure to alter application logic or bypass validation.
❌ Attack Example:
{
"username": "admin",
"password": "pass",
"isAdmin": true
} Attacker adds unauthorized fields
✓ Prevention:
// Strict schema validation
const allowedFields = ['username', 'password'];
const sanitized = {};
for (const field of allowedFields) {
if (data[field]) sanitized[field] = data[field];
} 3. Prototype Pollution
Modifying JavaScript object prototypes through malicious JSON.
❌ Vulnerable:
// Input: {"__proto__": {"admin": true}}
Object.assign(target, JSON.parse(input));
// Now ALL objects have admin: true ✓ Secure:
// Use Object.create(null) or validate
const parsed = JSON.parse(input);
if ('__proto__' in parsed) {
throw new Error('Invalid input');
} 4. Data Leakage
Accidentally exposing sensitive information in JSON responses.
❌ Dangerous:
{
"id": 123,
"username": "john",
"password_hash": "...",
"email": "[email protected]",
"api_key": "secret123"
} ✓ Safe:
{
"id": 123,
"username": "john",
"email": "[email protected]"
}
// Never expose passwords or keys Secure JSON Parsing
Always Validate Before Parsing
function safeJSONParse(input) {
// 1. Check input is string
if (typeof input !== 'string') {
throw new Error('Input must be string');
}
// 2. Check reasonable size
if (input.length > 1000000) { // 1MB
throw new Error('Input too large');
}
// 3. Try parsing with error handling
try {
const parsed = JSON.parse(input);
// 4. Validate structure
if (typeof parsed !== 'object') {
throw new Error('Invalid JSON structure');
}
// 5. Check for prototype pollution
if ('__proto__' in parsed || 'constructor' in parsed) {
throw new Error('Dangerous JSON detected');
}
return parsed;
} catch (error) {
throw new Error(`JSON parse error: ${error.message}`);
}
} Safe Parsing Best Practices
- ✓ Always use try-catch blocks
- ✓ Implement size limits
- ✓ Validate data structure after parsing
- ✓ Use JSON Schema validation
- ✓ Never eval() or new Function() with JSON
API Security Best Practices
1. Use HTTPS Always
Never transmit JSON over unencrypted HTTP in production.
- • Prevents man-in-the-middle attacks
- • Protects sensitive data in transit
- • Required for secure authentication
2. Implement CORS Properly
// Server-side CORS configuration
app.use((req, res, next) => {
// Don't use wildcard in production with credentials
res.header('Access-Control-Allow-Origin', 'https://yourdomain.com');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.header('Access-Control-Allow-Credentials', 'true');
next();
}); 3. Validate Content-Type
// Server-side validation
if (req.headers['content-type'] !== 'application/json') {
return res.status(400).json({ error: 'Invalid content type' });
} 4. Implement Rate Limiting
Prevent abuse and DoS attacks:
- • Limit requests per IP/user
- • Implement exponential backoff
- • Return 429 Too Many Requests
- • Use Redis or similar for tracking
Data Sanitization
Input Sanitization Function
function sanitizeJSON(data, schema) {
const sanitized = {};
for (const [key, rules] of Object.entries(schema)) {
if (!(key in data)) {
if (rules.required) {
throw new Error(`Missing required field: ${key}`);
}
continue;
}
let value = data[key];
// Type validation
if (typeof value !== rules.type) {
throw new Error(`Invalid type for ${key}`);
}
// String sanitization
if (rules.type === 'string') {
value = value.trim();
if (rules.maxLength && value.length > rules.maxLength) {
throw new Error(`${key} exceeds max length`);
}
// Remove potentially dangerous characters
if (rules.sanitize) {
value = value.replace(/[<>'"]/g, '');
}
}
// Number validation
if (rules.type === 'number') {
if (rules.min && value < rules.min) {
throw new Error(`${key} below minimum`);
}
if (rules.max && value > rules.max) {
throw new Error(`${key} above maximum`);
}
}
sanitized[key] = value;
}
return sanitized;
} Usage Example:
const schema = {
username: { type: 'string', required: true, maxLength: 50, sanitize: true },
email: { type: 'string', required: true, maxLength: 100 },
age: { type: 'number', min: 18, max: 120 }
};
const cleaned = sanitizeJSON(userInput, schema); Authentication & Authorization
JWT Security Best Practices
- → Use strong secret keys (256-bit minimum)
- → Set short expiration times
- → Implement refresh token rotation
- → Validate signature on every request
- → Never store sensitive data in JWT payload
- → Use HTTPS only for token transmission
API Key Security
- → Never embed keys in client-side code
- → Use environment variables for secrets
- → Implement key rotation policies
- → Log and monitor API key usage
- → Allow users to regenerate keys
Security Checklist
Always use HTTPS in production environments
Validate all inputs with schema validation
Sanitize data before display or storage
Implement rate limiting on all endpoints
Configure CORS correctly (no wildcards with credentials)
Never expose sensitive data in API responses
Use parameterized queries to prevent injection
Implement logging for security events
Regular security audits and penetration testing
Keep dependencies updated to patch vulnerabilities