JSONBeautify
    Back to Blog
    December 22, 20246 min read

    JSON Security: Preventing Common Vulnerabilities

    Security
    Best Practices

    JSON parsing seems straightforward, but careless handling can introduce security vulnerabilities. Learn how to parse JSON safely and protect your applications.

    Security Warning

    Never use eval() to parse JSON. It executes arbitrary code and is a major security risk.

    1. Never Use eval()

    Using eval() to parse JSON is extremely dangerous as it will execute any JavaScript code.

    Dangerous
    // NEVER DO THIS!
    const data = eval('(' + jsonString + ')');
    
    // Attacker can inject:
    // '(function(){/* malicious code */})()'
    Safe
    // Always use JSON.parse()
    const data = JSON.parse(jsonString);
    
    // Throws SyntaxError on invalid JSON
    // Cannot execute code

    2. Prototype Pollution

    Malicious JSON can modify object prototypes, affecting all objects in your application.

    // Malicious payload
    const malicious = '{"__proto__": {"isAdmin": true}}';
    
    // Unsafe merge operation
    const config = {};
    Object.assign(config, JSON.parse(malicious));
    
    // Now ALL objects have isAdmin: true
    const user = {};
    console.log(user.isAdmin); // true! Security breach!

    Prevention

    // Use Object.create(null) for config objects
    const config = Object.create(null);
    
    // Or filter dangerous keys
    function safeParse(jsonString) {
      return JSON.parse(jsonString, (key, value) => {
        if (key === '__proto__' || key === 'constructor') {
          return undefined;
        }
        return value;
      });
    }

    3. JSON Injection in Strings

    When embedding user data in JSON strings, always escape properly to prevent injection.

    // DON'T build JSON strings manually
    const json = '{"name": "' + userInput + '"}';
    // If userInput = '", "isAdmin": true, "x": "'
    // Result: {"name": "", "isAdmin": true, "x": ""}
    
    // DO use JSON.stringify()
    const data = { name: userInput };
    const json = JSON.stringify(data);
    // User input is properly escaped

    4. Denial of Service (DoS)

    Large or deeply nested JSON can crash your application or consume excessive resources.

    // Set limits on JSON size
    const MAX_JSON_SIZE = 1024 * 1024; // 1MB
    
    function parseWithLimit(jsonString) {
      if (jsonString.length > MAX_JSON_SIZE) {
        throw new Error('JSON exceeds size limit');
      }
      return JSON.parse(jsonString);
    }
    
    // For APIs, use middleware to limit body size
    app.use(express.json({ limit: '1mb' }));

    5. Sensitive Data Exposure

    Be careful not to include sensitive data in JSON responses or logs.

    // Define a toJSON method to control serialization
    class User {
      constructor(name, email, password) {
        this.name = name;
        this.email = email;
        this.password = password;
      }
      
      toJSON() {
        return {
          name: this.name,
          email: this.email
          // password is excluded
        };
      }
    }
    
    const user = new User('John', 'john@example.com', 'secret');
    console.log(JSON.stringify(user));
    // {"name":"John","email":"john@example.com"}

    Security Checklist

    • Always use JSON.parse(), never eval()
    • Validate and sanitize input before processing
    • Set size limits on JSON payloads
    • Filter dangerous keys like __proto__
    • Use schema validation for untrusted data
    • Implement proper error handling without leaking details
    • Audit third-party JSON parsing libraries

    Conclusion

    JSON security is often overlooked, but following these practices will help protect your applications from common vulnerabilities. Always treat JSON from external sources as potentially malicious and validate accordingly.

    © 2025 JSON Formatter. All rights reserved.