CWE-375: Returning a Mutable Object to an Untrusted Caller

Learn about CWE-375 (Returning a Mutable Object to an Untrusted Caller), its security impact, exploitation methods, and prevention guidelines.

What is Returning a Mutable Object to an Untrusted Caller?

• Overview: This vulnerability involves returning a mutable object from a method to an untrusted caller, which can then alter the object. This can lead to unexpected changes in the program's behavior as the original object is modified.

• Exploitation Methods:

  • Attackers can exploit this vulnerability by modifying the returned object to manipulate the application's data flow.
  • Common attack patterns include altering critical internal data structures and causing denial of service by injecting invalid data.

• Security Impact:

  • Direct consequences include unauthorized alterations to the internal state of an application.
  • Potential cascading effects could lead to unpredictable application behavior and security breaches if the object state is critical to security mechanisms.
  • Business impact may involve data corruption, loss of data integrity, and potential financial losses due to trust violations.

• Prevention Guidelines:

  • Specific code-level fixes include returning copies of mutable objects rather than the original objects.
  • Security best practices involve using immutable objects or defensive copying strategies to safeguard against modifications.
  • Recommended tools and frameworks include static analysis tools to detect potential vulnerabilities and language features that enforce immutability or encapsulation.

Corgea can automatically detect and fix Returning a Mutable Object to an Untrusted Caller in your codebase. Try Corgea free today.

Technical Details

Likelihood of Exploit: Medium

Affected Languages: C, C++, Java, C#

Affected Technologies: Not specified

Vulnerable Code Example

#include <stdio.h>
#include <stdlib.h>

// Function that returns a pointer to a mutable object
int* getMutableArray(int size) {
    if (size <= 0) {
        return NULL; // Handle invalid size input
    }
    int* array = malloc(size * sizeof(int));
    if (array == NULL) {
        return NULL; // Handle memory allocation failure
    }
    for (int i = 0; i < size; i++) {
        array[i] = i; // Initialize array with some values
    }
    return array; // Returning a mutable object to the caller
}

int main() {
    int* myArray = getMutableArray(5);
    if (myArray != NULL) {
        // Untrusted code can now modify the array
        myArray[0] = 100; // Potentially malicious modification
        free(myArray);
    }
    return 0;
}

Explanation of Vulnerability

  • The function getMutableArray returns a pointer to a heap-allocated array. This exposes the internal state of the array to the caller, allowing any modifications, which can lead to unintended side effects or security vulnerabilities if the caller is untrusted or malicious. The caller can alter the array contents, potentially affecting other parts of the program that rely on the original data integrity.

How to fix Returning a Mutable Object to an Untrusted Caller?

To mitigate this vulnerability, we need to ensure that the caller does not get direct access to the mutable object. This can be done by:

  1. Returning a copy of the object instead of the original, ensuring that any modifications by the caller do not affect the original object.
  2. If performance or memory usage is a concern, consider providing controlled access through accessor functions that do not expose the internal state directly.

Fixed Code Example

#include <stdio.h>
#include <stdlib.h>

// Function that returns a copy of the array
int* getArrayCopy(const int* originalArray, int size) {
    if (size <= 0) {
        return NULL; // Handle invalid size input
    }
    int* copy = malloc(size * sizeof(int));
    if (copy == NULL) {
        return NULL; // Handle memory allocation failure
    }
    for (int i = 0; i < size; i++) {
        copy[i] = originalArray[i]; // Copy values from the original array
    }
    return copy; // Return the copy instead of the original
}

int* getImmutableArray(int size) {
    if (size <= 0) {
        return NULL; // Handle invalid size input
    }
    int* array = malloc(size * sizeof(int));
    if (array == NULL) {
        return NULL; // Handle memory allocation failure
    }
    for (int i = 0; i < size; i++) {
        array[i] = i; // Initialize array with some values
    }
    int* arrayCopy = getArrayCopy(array, size); // Create a copy to return
    free(array); // Free the original array
    return arrayCopy; // Return the copy to the caller
}

int main() {
    int* myArray = getImmutableArray(5);
    if (myArray != NULL) {
        // Now, even if the caller modifies the array, it does not affect the original
        myArray[0] = 100; // This change does not affect the original
        free(myArray); // Free the copied array
    }
    return 0;
}

Explanation of Fix

  • The getImmutableArray function now returns a copy of the array rather than the original. This ensures that any modifications by the caller do not affect the original array, maintaining the integrity of the data.
  • getArrayCopy is a helper function that creates a copy of the array, ensuring that the caller only receives a safe copy, thus preventing any modifications to the original data.
  • Input validation is added to handle invalid size inputs, ensuring robustness against incorrect usage.
Corgea Logo

Find this vulnerability and fix it with Corgea

Scan your codebase for CWE-375: Returning a Mutable Object to an Untrusted Caller and get remediation guidance

Start for free and no credit card needed.