📗
Application Security Manual
  • Intro
    • Start Here
  • Vulnerabilities & Code
    • Injection Vulnerabilities
      • SQL Injection
      • Server-Side Template Injection (SSTI)
      • XPath Injection
      • XML External Entity (XXE) Injection
      • HTTP Request Smuggling
      • Insecure Deserialization
    • Input-based Vulnerabilities
      • Cross-Site Scripting (XSS)
      • Content Security Policy (CSP) Misconfiguration
      • HTTP Parameter Pollution
    • Origin-related Vulnerabilities
      • Cross-Site Request Forgery (CSRF)
      • Server-Side Request Forgery (SSRF)
      • Cross-Origin Resource Sharing (CORS) Misconfiguration
    • Access-related Vulnerabilities
      • Insecure Direct Object References (IDOR)
      • Authorization Code Interception
      • Session Hijacking
      • Insufficient Transport Layer Security (TLS)
      • JSON Web Token (JWT) Vulnerabilities
      • Insecure Client-Side Storage of JWTs
    • Logic & Timing Vulnerabilities
      • Business Logic Flaws
      • Type Juggling (Loose Type Comparison)
      • Timing Attack
  • Design Review
    • Product Security Design Review Framework
    • Security Design Review Checklist
  • Concepts & Culture
    • Implementing SAST Through Security-Driven Developer Culture
    • Security as Code: Baking Security into DevOps
Powered by GitBook
On this page
  • Concept
  • Vulnerable Scenario
  • Explanation
  • Prevention
  • Conclusion
  1. Vulnerabilities & Code
  2. Injection Vulnerabilities

Insecure Deserialization

Concept

Insecure deserialization is a vulnerability that occurs when untrusted or maliciously crafted data is deserialized by an application without proper validation or sanitization. Deserialization is the process of converting a serialized object, typically in a format like JSON, XML, or binary, back into a live object in the application's memory.

If an attacker can manipulate the serialized data and the application blindly deserializes it without proper checks, it can lead to serious security issues such as remote code execution, injection attacks, or unauthorized access to sensitive data.

Vulnerable Scenario

Consider a web application that accepts serialized objects from untrusted sources, such as user input or data from external systems. The application deserializes the received data directly, without proper validation or sanitization.

Example Code (Vulnerable)

import pickle
from flask import Flask, request

app = Flask(__name__)

@app.route('/deserialize', methods=['POST'])
def deserialize():
    serialized_data = request.get_data()
    obj = pickle.loads(serialized_data)
    
    # Process the deserialized object
    process_data(obj)
    
    return "Deserialization completed"

def process_data(obj):
    # Perform actions based on the deserialized object
    # ...

if __name__ == '__main__':
    app.run()

Explanation

In this example, the web application uses the pickle module in Python to deserialize data received through a POST request. The pickle.loads() function is used to deserialize the serialized_data directly, without any validation or sanitization.

An attacker can exploit this vulnerability by crafting a malicious payload and sending it to the /deserialize endpoint. For example, the attacker can create a serialized object that contains malicious code:

import pickle
import os

class MaliciousPayload:
    def __reduce__(self):
        return (os.system, ('rm -rf /',))

malicious_data = pickle.dumps(MaliciousPayload())

When the application deserializes this malicious payload using pickle.loads(), it will execute the os.system() function with the provided command, which in this case is 'rm -rf /', potentially causing destructive actions on the server.

Insecure deserialization can lead to various types of attacks, such as:

  • Remote code execution: Attackers can inject and execute arbitrary code on the server.

  • Injection attacks: Attackers can manipulate the deserialized data to perform SQL injection, command injection, or other types of injection attacks.

  • Privilege escalation: Attackers can exploit deserialization to gain unauthorized access to sensitive resources or elevate their privileges.

  • Denial of Service (DoS): Attackers can craft malicious payloads that cause the application to crash or consume excessive resources.

Prevention

To prevent insecure deserialization vulnerabilities, consider the following measures:

  1. Avoid using insecure deserialization libraries: Some deserialization libraries, such as Python's pickle, are inherently insecure and should be avoided. Use secure alternatives like json or yaml that do not allow arbitrary code execution.

  2. Validate and sanitize serialized data: Before deserializing the data, validate and sanitize it to ensure it meets the expected format and does not contain any malicious content. Reject or sanitize any data that fails the validation checks.

  3. Implement type checks and whitelisting: When deserializing objects, verify that the deserialized data matches the expected types and structures. Use whitelisting to allow only specific classes or data types to be deserialized.

  4. Authenticate and authorize deserialization: Ensure that the deserialization process is performed only by authenticated and authorized users or systems. Restrict deserialization to trusted sources and validate the integrity of the serialized data.

  5. Limit the scope of deserialized objects: Minimize the attack surface by deserializing objects with limited functionality and privileges. Avoid deserializing objects that have access to sensitive resources or can perform dangerous actions.

  6. Keep deserialization libraries and dependencies up to date: Regularly update the deserialization libraries and dependencies to ensure they include the latest security patches and fixes for known vulnerabilities.

Example Code (Secure)

import json
from flask import Flask, request

app = Flask(__name__)

@app.route('/deserialize', methods=['POST'])
def deserialize():
    serialized_data = request.get_data()
    
    try:
        data = json.loads(serialized_data)
        # Validate and sanitize the deserialized data
        if not is_valid_data(data):
            return "Invalid data", 400
        
        # Process the validated data
        process_data(data)
        
        return "Deserialization completed"
    except json.JSONDecodeError:
        return "Invalid JSON", 400

def is_valid_data(data):
    # Perform validation checks on the deserialized data
    # Example: Check if the data is a dictionary and contains expected keys
    if not isinstance(data, dict):
        return False
    if 'key1' not in data or 'key2' not in data:
        return False
    return True

def process_data(data):
    # Perform actions based on the validated data
    # ...

if __name__ == '__main__':
    app.run()

In the secure example, the application uses the json module to deserialize the data, which is safer than using pickle. The json.loads() function is used to parse the serialized data into a Python object.

Before processing the deserialized data, the is_valid_data() function is called to validate and sanitize the data. It checks if the deserialized data is a dictionary and contains the expected keys. If the validation fails, an error response is returned.

By validating and sanitizing the deserialized data, the application reduces the risk of insecure deserialization attacks. It ensures that only expected and valid data is processed, preventing the execution of malicious code or unauthorized actions.

Conclusion

Insecure deserialization is a serious vulnerability that can lead to remote code execution, injection attacks, and other critical security issues. It occurs when an application deserializes untrusted or maliciously crafted data without proper validation or sanitization.

To mitigate the risks of insecure deserialization, it is crucial to use secure deserialization libraries, validate and sanitize serialized data, implement type checks and whitelisting, authenticate and authorize deserialization, limit the scope of deserialized objects, and keep libraries and dependencies up to date.

Developers should be cautious when deserializing data from untrusted sources and ensure that appropriate security measures are in place to prevent insecure deserialization vulnerabilities.

Semgrep Rule

Semgrep can be used to identify instances where insecure deserialization libraries, such as pickle, are used in the application.

rules:
  - id: insecure-deserialization
    patterns:
      - pattern: pickle.loads(...)
    message: "Insecure deserialization using 'pickle' library. Use secure alternatives like 'json' or 'yaml' instead."
    languages:
      - python
    severity: ERROR

This Semgrep rule identifies code patterns where the pickle.loads() function is used to deserialize data. It suggests using secure alternatives like json or yaml to prevent insecure deserialization vulnerabilities.

Note that this rule is a starting point and may need to be adapted based on your specific application and security requirements. It is important to thoroughly review and test the deserialization process to ensure that it is secure and follows best practices.

PreviousHTTP Request SmugglingNextInput-based Vulnerabilities

Last updated 1 year ago