MEDIUM CWE-415 Memory Safety

CWE-415 in APIs

CWE ID
CWE-415
Category
Input Validation
Severity
CRITICAL
Short Name
Double Free

What is Cwe 415?

Cwe 415: Double Free occurs when a program attempts to free the same memory location twice. This weakness can lead to memory corruption, crashes, or even exploitable conditions where an attacker can execute arbitrary code.

The weakness typically manifests when:

  • A pointer to allocated memory is freed, then the pointer is reused or re-freed
  • Multiple code paths free the same resource without proper state tracking
  • Error handling paths free resources that were already freed in the normal execution path

Double free vulnerabilities are particularly dangerous because they can corrupt the heap allocator's internal data structures, potentially allowing an attacker to overwrite function pointers or control program flow.

Remediation

Fixing Cwe 415 requires careful resource management and defensive programming:

1. Use RAII/Smart Pointers (C++/Rust)

// C++ - use smart pointers to prevent double free
std::unique_ptr<Resource> resource = std::make_unique<Resource>();
// No need to manually free - unique_ptr handles it

2. Nullify Pointers After Free

void cleanup(Resource* res) {
    if (res != NULL) {
        free(res);
        res = NULL; // Prevent reuse
    }
}

3. Use Reference Counting

# Python - use context managers
class Resource:
    def __enter__(self):
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.cleanup()
        # Only cleaned up once when exiting context

with Resource() as res:
    process(res)
# Automatically cleaned up here, even if process() raises

4. Implement Safe Cleanup Patterns

// Node.js - safe cleanup with flags
function processRequest(data) {
    let cleanedUp = false;
    
    try {
        const result = processData(data);
        return result;
    } catch (error) {
        throw error;
    } finally {
        if (!cleanedUp) {
            cleanup(data);
            cleanedUp = true;
        }
    }
}

5. Use Modern Frameworks with Built-in Safety

Modern web frameworks handle resource management automatically:

// Express.js - let the framework handle cleanup
app.post('/api/data', async (req, res) => {
    try {
        const result = await processData(req.body);
        res.json(result);
    } catch (error) {
        res.status(500).json({error: 'Processing failed'});
    }
    // No manual cleanup needed - Express handles response cleanup
});

6. Implement Comprehensive Error Handling

// Go - use defer for guaranteed cleanup
def processRequest(w http.ResponseWriter, r *http.Request) {
    db, err := dbPool.Get()
    if err != nil {
        http.Error(w, "DB error", 500)
        return
    }
    defer db.Close() // Guaranteed to run once
    
    // Process request
    result, err := processData(db, r.Body)
    if err != nil {
        http.Error(w, err.Error(), 400)
        return
    }
    
    json.NewEncoder(w).Encode(result)
}

The key principle is ensuring resources are freed exactly once, regardless of which code path is taken. Using modern language features, framework abstractions, and defensive programming patterns eliminates most double free vulnerabilities.

Frequently Asked Questions

How does Cwe 415 differ from use-after-free?
Cwe 415 (Double Free) involves freeing the same memory twice, while use-after-free involves accessing memory after it has been freed. Both are memory corruption issues, but double free corrupts the allocator's metadata, while use-after-free can lead to reading stale data or crashing when the memory has been reallocated.
Can Cwe 415 lead to remote code execution?
Yes, double free vulnerabilities can potentially lead to remote code execution in languages like C/C++. By carefully timing double free operations, an attacker might overwrite heap metadata to control function pointers or return addresses. However, modern operating systems and runtime protections (ASLR, DEP) make exploitation significantly more difficult.