# Insecure Deserialization

#### Insecure Deserialization in Java

**Vulnerability:** Insecure Deserialization

**Vulnerable Code:**

```java
javaCopy codeObjectInputStream ois = new ObjectInputStream(new FileInputStream("data.ser"));
Object obj = ois.readObject();
```

**Reason for vulnerability:** Deserializing untrusted data can lead to remote code execution or other security issues.

**Fixed Code:**

```java
javaCopy codeObjectInputStream ois = new ObjectInputStream(new FileInputStream("data.ser")) {
    @Override
    protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
        if (!allowedClasses.contains(desc.getName())) {
            throw new InvalidClassException("Unauthorized deserialization attempt", desc.getName());
        }
        return super.resolveClass(desc);
    }
};
Object obj = ois.readObject();
```

**Reason for fix:** Restricting the classes that can be deserialized prevents malicious code execution.

***

#### Insecure Deserialization in Python

**Vulnerability:** Insecure Deserialization

**Vulnerable Code:**

```python
pythonCopy codeimport pickle

data = pickle.loads(request.data)
```

**Reason for vulnerability:** Deserializing untrusted data with `pickle` can lead to arbitrary code execution.

**Fixed Code:**

```python
pythonCopy codeimport json

data = json.loads(request.data)
```

**Reason for fix:** Using `json` for deserialization instead of `pickle` prevents arbitrary code execution since `json` only handles basic data types.

***

**Example 2: Python**

**Vulnerable Code:**

```python
pythonCopy codeobj = pickle.load(open('file.pkl', 'rb'))
```

**Reason for vulnerability:** Deserializing untrusted data, leading to insecure deserialization.

**Fixed Code:**

```python
pythonCopy codeclass SafeUnpickler(pickle.Unpickler):
    def find_class(self, module, name):
        if module == "allowed.module" and name == "AllowedClass":
            return super().find_class(module, name)
        raise pickle.UnpicklingError("Unauthorized deserialization attempt")

obj = SafeUnpickler(open('file.pkl', 'rb')).load()
```

**Reason for fix:** Restrict the classes that can be deserialized.

***

### Java Example

#### Vulnerable Code:

```java
javaCopyimport java.io.*;

public class UserDeserializer {
    public static User deserializeUser(String serializedUser) {
        try (ByteArrayInputStream bis = new ByteArrayInputStream(Base64.getDecoder().decode(serializedUser));
             ObjectInputStream ois = new ObjectInputStream(bis)) {
            return (User) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }
}
```

#### Reason for Vulnerability:

This code blindly deserializes user-provided data, which can lead to remote code execution if the User class or any of its members are not designed securely.

#### Fixed Code:

```java
javaCopyimport com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;

public class UserDeserializer {
    private static final ObjectMapper mapper = JsonMapper.builder()
            .activateDefaultTyping(null, ObjectMapper.DefaultTyping.NON_FINAL)
            .build();

    public static User deserializeUser(String serializedUser) {
        try {
            return mapper.readValue(serializedUser, User.class);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}
```

#### Reason for Fix:

The fixed code uses Jackson for JSON deserialization instead of Java's built-in serialization. This approach is generally safer and allows for fine-grained control over deserialization behavior.

### Java Example

#### Vulnerable Code:

```java
javaCopyimport org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;

public class CommandExecutor {
    public static void executeCommand(String command) {
        InvokerTransformer transformer = new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{command});
        Map<String, String> map = new HashMap<String, String>();
        map.put("key", "value");
        Map<String, String> transformedMap = TransformedMap.decorate(map, null, transformer);
        // Use transformedMap...
    }
}
```

#### Reason for Vulnerability:

This code uses Apache Commons Collections' TransformedMap with InvokerTransformer, which can be exploited in deserialization attacks to execute arbitrary commands.

#### Fixed Code:

```java
javaCopyimport java.util.HashMap;
import java.util.Map;

public class CommandExecutor {
    public static void executeCommand(String command) {
        // Validate and sanitize the command
        if (!isValidCommand(command)) {
            throw new IllegalArgumentException("Invalid command");
        }
        // Execute the command safely
        ProcessBuilder processBuilder = new ProcessBuilder(command.split("\\s+"));
        processBuilder.start();
    }

    private static boolean isValidCommand(String command) {
        // Implement command validation logic
        return command.matches("^[a-zA-Z0-9\\s-]+$");
    }
}
```

#### Reason for Fix:

The fixed code removes the use of potentially dangerous Apache Commons Collections classes and implements a safer way to execute commands with proper validation.

### Python Example

#### Vulnerable Code:

```python
pythonCopyimport pickle
import base64

def process_data(encoded_data):
    data = base64.b64decode(encoded_data)
    return pickle.loads(data)
```

#### Reason for Vulnerability:

This code uses Python's pickle module to deserialize data, which can lead to arbitrary code execution if an attacker controls the serialized data.

#### Fixed Code:

```python
pythonCopyimport json
import base64

def process_data(encoded_data):
    data = base64.b64decode(encoded_data)
    return json.loads(data)
```

#### Reason for Fix:

The fixed code uses JSON for deserialization instead of pickle. JSON is a data-only format and doesn't allow for code execution, making it a safer choice for deserializing untrusted data.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://playbook.sidthoviti.com/devsecops/secure-coding/code-review-examples/insecure-deserialization.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
