Skip to main content
Security Guide

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