Creation of Emergent Resource

Description

Creation of Emergent Resource occurs when a product manages resources or behaves in a way that indirectly creates a new, distinct resource that can be used by attackers in violation of the intended policy. Systems sometimes produce unintended resource types through complex behavior. Rather than explicitly allocating resources as designed, indirect resource creation can emerge—such as covert channels that attackers exploit. A classic example is "parasitic computing" where a product might unknowingly perform computations for external parties.

Risk

Emergent resource creation has significant security implications. Covert channels may be created unintentionally. Timing side channels may leak sensitive information. Resources may be consumed by unauthorized parties. System behavior may be exploited for unintended purposes. Information may flow through unmonitored channels. Access controls may be bypassed through emergent paths. Cryptographic secrets may be leaked through side channels. System resources may be abused for parasitic computing.

Solution

Analyze system behavior for unintended resource creation. Implement constant-time algorithms where timing matters. Monitor for unexpected resource usage patterns. Design systems with minimal observable state changes. Implement proper isolation between components. Use formal methods to identify emergent behaviors. Test for timing variations that could leak information. Document and review all external interfaces. Consider all observable system behaviors as potential channels.

Common Consequences

ImpactDetails
OtherScope: Other

Varies by Context - The impact depends on the specific emergent resource created. Could enable covert channels, side-channel attacks, or unauthorized resource usage.
ConfidentialityScope: Confidentiality

Information Disclosure - Emergent channels may leak sensitive information through timing, power consumption, or other observable behaviors.

Example Code

Vulnerable Code

# Vulnerable: Timing-based side channel in password validation

def vulnerable_validate_password(actual_pw, typed_pw):
    # VULNERABLE: Early return creates timing side channel
    if len(actual_pw) != len(typed_pw):
        return False

    # VULNERABLE: Character-by-character comparison leaks position
    for i in range(len(actual_pw)):
        if actual_pw[i] != typed_pw[i]:
            return False  # Returns early on mismatch

    return True

# Attack: Measure time to determine password length and characters
# - Wrong length: very fast rejection
# - Correct length, wrong first char: slightly longer
# - Correct first char, wrong second: even longer
# - Continue until entire password discovered
// Vulnerable: Timing leak in cryptographic comparison

#include <stdbool.h>
#include <string.h>

// VULNERABLE: memcmp may return early on mismatch
bool vulnerable_verify_mac(const uint8_t* expected, const uint8_t* actual, size_t len) {
    return memcmp(expected, actual, len) == 0;
}

// VULNERABLE: Loop exits early, creating timing channel
bool vulnerable_compare_tokens(const char* token1, const char* token2) {
    if (strlen(token1) != strlen(token2)) {
        return false;  // Length check leaks information
    }

    for (int i = 0; token1[i] != '\0'; i++) {
        if (token1[i] != token2[i]) {
            return false;  // Early exit leaks position
        }
    }
    return true;
}
// Vulnerable: Cache timing side channel

public class VulnerableLookup {
    private static final byte[] SECRET_TABLE = loadSecretTable();

    // VULNERABLE: Array access time depends on cache state
    public static byte lookupSecret(int index) {
        // If index was recently accessed, lookup is fast (cached)
        // If not, lookup is slow (cache miss)
        // Attacker can probe cache to discover access patterns
        return SECRET_TABLE[index];
    }

    // VULNERABLE: Conditional branch based on secret
    public static boolean checkBit(byte secret, int position) {
        if ((secret & (1 << position)) != 0) {
            // Branch taken - different timing/cache behavior
            return true;
        } else {
            // Branch not taken - different timing/cache behavior
            return false;
        }
    }
}
# Vulnerable: Resource-based side channel

import time

class VulnerableRateLimiter:
    def __init__(self):
        self.user_requests = {}  # Username -> timestamp list

    def check_rate_limit(self, username):
        # VULNERABLE: Different behavior reveals if user exists
        if username not in self.user_requests:
            # New user - allocates memory, takes longer
            self.user_requests[username] = []
            return True
        else:
            # Existing user - just checks list, faster
            recent = [t for t in self.user_requests[username]
                     if time.time() - t < 60]
            self.user_requests[username] = recent
            return len(recent) < 10

# Attack: Time responses to enumerate valid usernames

Fixed Code

# Fixed: Constant-time password validation

import hmac

def secure_validate_password(actual_pw, typed_pw):
    # Use constant-time comparison
    # hmac.compare_digest is designed to prevent timing attacks

    # Pad to same length if needed (or use hash comparison)
    actual_bytes = actual_pw.encode('utf-8')
    typed_bytes = typed_pw.encode('utf-8')

    # Always compare same-length values
    return hmac.compare_digest(actual_bytes, typed_bytes)


# Alternative: Compare password hashes
import hashlib

def secure_validate_password_hash(stored_hash, typed_pw, salt):
    # Hash the typed password
    typed_hash = hashlib.pbkdf2_hmac('sha256', typed_pw.encode(),
                                      salt, 100000)

    # Constant-time comparison of hashes
    return hmac.compare_digest(stored_hash, typed_hash)
// Fixed: Constant-time cryptographic comparison

#include <stdbool.h>
#include <stdint.h>

// Constant-time comparison - always examines all bytes
bool secure_compare(const uint8_t* a, const uint8_t* b, size_t len) {
    volatile uint8_t result = 0;

    for (size_t i = 0; i < len; i++) {
        result |= a[i] ^ b[i];
    }

    return result == 0;
}

// Constant-time MAC verification
bool secure_verify_mac(const uint8_t* expected, const uint8_t* actual, size_t len) {
    return secure_compare(expected, actual, len);
}

// Constant-time conditional select (no branch)
uint32_t constant_time_select(uint32_t condition, uint32_t a, uint32_t b) {
    // condition must be 0 or 1
    // Returns a if condition is 1, b if condition is 0
    uint32_t mask = ~(condition - 1);  // All 1s if condition==1, all 0s if 0
    return (a & mask) | (b & ~mask);
}
// Fixed: Preventing cache timing attacks

import java.security.MessageDigest;

public class SecureLookup {
    private static final byte[] SECRET_TABLE = loadSecretTable();

    // Fixed: Access all elements to prevent cache timing
    public static byte lookupSecretConstantTime(int index) {
        byte result = 0;

        for (int i = 0; i < SECRET_TABLE.length; i++) {
            // Constant-time conditional: select without branching
            int mask = constantTimeEquals(i, index);
            result = (byte)((result & ~mask) | (SECRET_TABLE[i] & mask));
        }

        return result;
    }

    // Constant-time equality check
    private static int constantTimeEquals(int a, int b) {
        // Returns all 1s if equal, all 0s if not
        int x = a ^ b;
        x = ~x;
        // Propagate any 0 bit to make result 0
        x &= x >> 16;
        x &= x >> 8;
        x &= x >> 4;
        x &= x >> 2;
        x &= x >> 1;
        return x & 1;
    }

    // Fixed: Constant-time MAC verification
    public static boolean verifyMac(byte[] expected, byte[] actual) {
        return MessageDigest.isEqual(expected, actual);
    }
}
# Fixed: Resource-neutral rate limiter

import time
import hashlib

class SecureRateLimiter:
    def __init__(self):
        self.request_buckets = {}  # Hash -> timestamp list

    def check_rate_limit(self, username):
        # Hash username so storage doesn't reveal existence
        user_hash = hashlib.sha256(username.encode()).hexdigest()

        # Always perform same operations regardless of user existence
        current_time = time.time()

        if user_hash not in self.request_buckets:
            self.request_buckets[user_hash] = []

        # Always filter and count
        recent = [t for t in self.request_buckets[user_hash]
                 if current_time - t < 60]

        # Always update
        self.request_buckets[user_hash] = recent

        # Always add current request (will be cleaned up if over limit)
        if len(recent) < 10:
            self.request_buckets[user_hash].append(current_time)
            return True

        return False

    # Periodically clean up to prevent unbounded growth
    def cleanup_old_buckets(self):
        current_time = time.time()
        for key in list(self.request_buckets.keys()):
            self.request_buckets[key] = [
                t for t in self.request_buckets[key]
                if current_time - t < 60
            ]
            if not self.request_buckets[key]:
                del self.request_buckets[key]

CVE Examples

Side-channel vulnerabilities have been discovered in numerous cryptographic implementations, including Spectre and Meltdown (CPU cache timing), Lucky 13 (TLS padding oracle), and various password timing attacks.


  • CWE-664: Improper Control of a Resource Through its Lifetime (parent)
  • CWE-514: Covert Channel (child)
  • CWE-208: Observable Timing Discrepancy (related)

References

  1. MITRE Corporation. "CWE-1229: Creation of Emergent Resource." https://cwe.mitre.org/data/definitions/1229.html
  2. Wikipedia. "Parasitic computing"
  3. Side-Channel Attack Mitigation Guidelines