Page cover

Dumb ways to get rekt w/ TEEs

Introduction

Trusted Execution Environments (TEEs) are often treated as if they provide “hardware-level security” by default, and while physical security of TEEs is a different beast, the moment you move to cloud-managed TEEs (AWS Nitro, Azure Confidential VMs, Google CC, etc.), the threat model changes drastically. Physical attacks become extremely hard to pull off, but implementation-level mistakes, bad assumptions, and misconfigured attestation suddenly become the primary attack surface.

This page outlines the real threats that emerge when building with TEEs in cloud environments, especially for Web3 systems. Most failures we see today aren’t due to broken hardware. They’re due to developers trusting things they shouldn’t, skipping essential verification steps, or exposing side channels without realising it. Understanding these threat models is the difference between a secure TEE deployment and an imminent exploit.

Changes in the Threat landscape because of Cloud

The threat landscape for TEEs has fundamentally changed now that most people use AWS Nitro Enclaves, Azure Confidential VMs, Google Cloud Confidential Computing, or managed SGX services instead of bare metal.

Physical attacks (like WireTap, voltage glitching, EM injection) become much harder:

  • Cloud providers control physical access to data centers with extensive security

  • No local access to memory bus, voltage regulators, or EM injection points

  • Supply chain security handled by hyperscale providers with sophisticated controls

  • Rowhammer is mitigated through ECC memory and instance isolation policies

But implementation-level vulnerabilities become the primary attack vector:

  • Developers make software mistakes when using TEE APIs and SDKs

  • Misconfiguration is now the #1 cause of cloud breaches (25% of incidents)

  • Logic errors in enclave-to-parent communication create exploitable conditions

  • Cryptographic implementation flaws defeat the security properties TEEs provide

The result: Even though the hardware is secure, the way developers use it creates massive vulnerabilities.


Threat 0: Trusting the Parent Instance

The Core Misunderstanding

Teams often assume the parent EC2 instance is part of their trusted computing base. They believe the host environment is cooperative because they control the instance.

This is wrong.

The Reality

You must treat the parent instance, its OS and the hypervisor as adversarial. Everything outside the enclave boundary can be influenced or observed by an attacker. The enclave is the only trusted component. All other layers can be manipulated.

Threat Model Details

If the parent instance is compromised, attackers can influence almost every interaction with the enclave.

1. Full Control Over the Host Software Stack

The attacker can control the OS, kernel, drivers and startup environment. They can supply malformed inputs, override configuration values or trigger unexpected code paths.

2. Manipulation of vsock and IPC Channels

All communication between the enclave and the outside world flows through the host. The attacker can intercept, modify, reorder, drop, replay or inject messages. Even if payloads are encrypted, message integrity and ordering must be enforced by the enclave.

3. Observation of Traffic Metadata and Timing

The host can observe message sizes and timing patterns. PacketSensei notes that the host can make near system clock level timing measurements. If two code paths differ in timing, the host can infer what the enclave is processing without seeing plaintext content.

4. Control Over Scheduling and Resource Availability

The host can delay or starve the enclave, reset it at specific times or disrupt time sensitive logic. Any protocol that depends on consistent timing or fairness must assume the host will try to interfere.

5. Influence Over Time and Randomness

If the enclave consumes time or randomness from the host, attackers can bias nonces, replay windows or expiry checks. Host supplied values should never be trusted.

Takeaway

The parent instance is not a trusted helper. It is a potential adversary with full visibility into traffic patterns and full influence over communication, timing and resource availability. Every message, state transition and configuration value entering the enclave must be authenticated and validated. Treat the enclave as the only trusted boundary in the system.


Threat 1: Trusting Enclave Identity Without Pinning Measurements

A TEE attestation only proves that the hardware is genuine and that some code is running inside it. The attestation does not guarantee that the code is the specific version you audited. If you do not pin a measurement or an allowlist of approved measurements, a cloud operator or attacker can replace the enclave image with a modified variant while still producing a valid attestation. The platform will happily attest to any code you provide. Without pinning, your verifier will not detect this change. Your enclave identity must be treated as an anchor of trust. A verifier must explicitly compare the reported measurement (to a pinned measurement or pinned whitelist of measurements), security version and debug attributes to a strict policy. Any deviation must cause immediate rejection.


Threat 2: Incomplete Attestation Verification

The Core Misunderstanding

What developers often do:

They verify the attestation document only by checking PCR-0 (the hash of the Enclave Image File, EIF). Their logic is simple: If PCR-0 matches what I expect, I can trust the enclave’s code.

Reality:

This is dangerously incomplete. Attestation proves much more than just the code running in your enclave. The attestation report contains multiple Platform Configuration Registers (PCRs), each representing a different part of the environment that impacts the enclave’s security posture.

What Attestation Actually Proves:

  • PCR-0: Enclave image file (EIF) measurement

  • PCR-1: Linux kernel and bootstrap measurement

  • PCR-2: Application measurement

  • PCR-3: IAM role assigned to parent instance

  • PCR-4: Instance ID of parent

  • PCR-8: Enclave image file signing certificate

Attack: Attacker runs your EIF (matching PCR-0) but with a different kernel (PCR-1) that has known vulnerabilities. Or they run with a malicious application that manipulates behavior (PCR-2).

  • PCR-0 = Docker image content

  • PCR-1, PCR-2, etc. = everything else in the enclave deployment

  • A secure Web3 protocol on TEEs will check all relevant PCRs, not just PCR-0 and the Dockerfile!


Threat 3: Exposing Secrets Through Logging Outside the Enclave

The most common unintentional leak in TEE systems is through logs. Developers often log decrypted requests, sensitive intermediate values, key material, error strings or user data. These logs then travel to external systems such as CloudWatch, Stackdriver, ELK or other centralised logging services. Once a secret leaves the enclave boundary, it is effectively public.

For TEE backed protocols, all logs outside the enclave must be treated as untrusted and publicly visible. No sensitive information should ever appear in logs. If logging is necessary for debugging or analytics, only hashed identifiers or aggregated statistics should be recorded.


Threat 4: Relying On Host-Provided Randomness Or Host Time

If the enclave relies on entropy or timestamps supplied by the parent instance, the host can influence the behaviour of the TEE. Host controlled randomness allows predictable or biased keys, nonces or challenges. Host controlled time lets attackers manipulate expiry windows, replay logic, auctions and scheduling.

All time-critical and randomness-critical logic must be generated inside the enclave using TEE native RNG. If trusted time is required, use consensus based time sources or external attestation verified time beacons. Never trust the host for either of these values.


Threat 5: Bloating The TCB By Running Excessive Logic Inside The Enclave

Every additional function, library or subsystem inside the enclave increases the Trusted Computing Base. Larger TCBs contain more bugs, more complexity and more undefined behaviour. This increases the difficulty of reasoning about correctness and confidentiality. It also magnifies the blast radius of any single vulnerability.

The enclave should only contain logic that strictly requires confidentiality or hardware-level integrity. Everything else should be pushed out to the untrusted world and guarded by cryptographic verification. Smaller enclaves are easier to audit, easier to reason about and significantly safer.


Threat 6: Not verifying the AWS root certificate

Core Misunderstanding

Bad practice:

Developers use the certificate bundled with the attestation document to verify its signature without checking that the certificate actually chains to AWS’s trusted root CA.

False assumption:

“If it’s signed by a certificate in the attestation, it must be legit.”

Attack Scenario:

  • Attacker generates a fake certificate chain (self-signed or malicious CA).

  • Signs a forged attestation document (e.g., for a malicious enclave, tampered PCRs, or manipulated application stack).

  • Present this document to your protocol/service.

  • Your app accepts the attestation because it only verifies the embedded certificate signature—without validating it chains up to AWS’s legit root.

Result:

You trust a completely unverified/malicious enclave. Attacker can claim any PCR values, any code, any identity.

Remediation:

You MUST validate the attestation certificate chain as follows:

  1. Obtain the official AWS Nitro Enclaves root CA certificate.

    • Available from AWS documentation.

  2. Check that the certificate used to sign the attestation:

    • Is part of a valid X.509 chain.

    • The chain terminates at the trusted AWS enclave root CA.

    • All intermediate CAs are valid and unrevoked.

  3. Verify the attestation document’s signature using only a chain trusted up to AWS root.

Web3 Protocol Implications

  • Critical for DeFi, bridges, privacy pools, oracles, and hybrid off-chain computation:

    • Only trust results, prices, bids, key operations, and confidential logic verified by an attestation chain anchored to AWS’s (or your TEE vendor’s) real root CA.

  • Audits and bug bounties:

    Always check that enclave verification strictly enforces certificate chain validation—not just the signature.

Conclusion

Never trust an enclave attestation by signature alone. Always mandate certificate chain verification up to the official AWS Nitro Enclaves root CA, or you open the door for total compromise.


Threat 7: Virtual Socket (vsock) Vulnerabilities

The vsock is the only communication channel between enclave and parent. It's also the primary attack surface. Vsocks are managed by the hypervisor—the hypervisor provides the parent EC2 instance’s and the enclave’s kernels with /dev/vsock device nodes

https://github.com/aws/aws-nitro-enclaves-cli/blob/c4fafb2320bc13d1e74e6ba2c1b6ef840cba0988/eif_loader/src/lib.rs#L54-L56

Vsocks are identified by a context identifier (CID) and port. Every enclave must use a unique CID, which can be set during initialization and can listen on multiple ports. There are a few predefined CIDs:

  • VMADDR_CID_HYPERVISOR = 0

  • VMADDR_CID_LOCAL = 1

  • VMADDR_CID_HOST = 2

  • VMADDR_CID_PARENT= 3 (the parent EC2 instance)

  • VMADDR_CID_ANY = 0xFFFFFFFF = -1U (listen on all CIDs)

Enclaves usually use only the VMADDR_CID_PARENT CID (to send data) and the VMADDR_CID_ANY CID (to listen for data).

Vulnerability 1: No Timeouts Leading to DoS

Attack: Parent never sends data, enclave hangs forever. Or parent sends data 1 byte at a time extremely slowly, tying up enclave resources.

# WRONG - Blocking forever on vsock
def handle_request():
    conn, addr = vsock_socket.accept()  # Blocks forever
    data = conn.recv(1024)  # Blocks forever
    process(data)

Remediation:

# CORRECT - Strict timeouts
def handle_request():
    vsock_socket.settimeout(5.0)  # 5 second timeout
    try:
        conn, addr = vsock_socket.accept()
        conn.settimeout(5.0)
        
        # Use async I/O with timeout
        data = await asyncio.wait_for(
            conn.recv(1024),
            timeout=5.0
        )
        
        process(data)
        
    except asyncio.TimeoutError:
        logger.warning("vsock timeout - potential DoS")
        return error_generic()

Conclusion: Implement socket timeouts and async connection handling to prevent denial-of-service through VSOCK blocking.


Vulnerability 2: Information Leakage Through Error Messages

# WRONG - Detailed error messages
def process_encrypted_data(data):
    try:
        decrypted = decrypt(data)
    except InvalidPaddingError:
        return "Error: Invalid padding in ciphertext"
    except InvalidKeyError:
        return "Error: Decryption key is invalid"
    except MACVerificationError:
        return "Error: MAC verification failed"

Attack: Parent sends malformed inputs and learns internal state from error messages. This creates a padding oracle attack—by observing which specific error occurs, attacker learns information about the plaintext.

# CORRECT - Generic error messages only
def process_encrypted_data(data):
    try:
        decrypted = decrypt(data)
        return decrypted
    except Exception:
        # All errors return same generic message
        # Log detailed error internally, not to parent
        internal_logger.error(f"Decryption failed: {traceback.format_exc()}")
        return error_generic("Operation failed")

Vulnerability 3: Timing Oracle Attacks

# WRONG - Variable timing reveals secrets
def verify_password(password_hash):
    stored_hash = get_stored_hash()
    
    # String comparison short-circuits on first mismatch
    if password_hash == stored_hash:
        return True
    return False

Attack: Parent measures how long verification takes. If passwords differ in first byte, comparison returns quickly. If they match for more bytes, it takes longer. Parent can brute-force password byte-by-byte.

# CORRECT - Constant-time comparison
import hmac

def verify_password(password_hash):
    stored_hash = get_stored_hash()
    
    # hmac.compare_digest is constant-time
    if hmac.compare_digest(password_hash, stored_hash):
        # Add random delay to prevent timing analysis
        time.sleep(random.uniform(0.01, 0.05))
        return True
    
    # Same random delay on failure path
    time.sleep(random.uniform(0.01, 0.05))
    return False

Conclusion: Implement all cryptographic operations in constant time. Network jitter provides no protection in this threat model


Vulnerability 4: Lack of Replay Protection on IPC or vsock Messages

Many protocols focus on encrypting the payload but ignore replay protection. If the parent instance is malicious and messages do not contain authenticated sequence numbers or nonces, any previously valid request can be replayed. This can re-trigger sensitive operations such as withdrawals, key usage, state transitions, approvals or attestation exchanges. Every request entering the enclave must contain a monotonic counter or nonce that is authenticated with a MAC. The enclave must track expected sequence numbers and reject duplicates or out of order messages. This is a foundational requirement for any protocol where the host is NOT trusted.


Threat 8: MEV Extraction and Front-Running

Attack 1.1: Encrypted Mempool Leakage via Parent Instance Trust

Affected Protocols: Flashbots SUAVE, PROF (Protected Order Flow), Unichain, TEN Protocol, any encrypted mempool design

The Promise: "Your transactions stay private until execution. No front-running!"

Simple Scenario:

You want to buy $1M worth of a token on a DEX using an encrypted mempool to avoid front-running. Here's what happens:

  1. Your wallet encrypts the transaction and sends it to the TEE-based mempool

  2. The TEE decrypts it inside the enclave: "Buy 1M USDC worth of TOKEN"

  3. The TEE processes the transaction, communicating with parent over vsock

  4. The fuckup: vsock carries unencrypted metadata:

    • Packet size: Large packet = big trade

    • Timing: Swap transactions take 150ms to validate, transfers take 50ms

    • Connection count: Multiple connections = complex DeFi interaction

    • Gas estimation: High gas = valuable transaction

  5. The MEV bot operator controls the parent instance (it's running in their cloud)

  6. They monitor vsock traffic with a simple script:

# MEV bot on parent instance
def sniff_vsock():
    while True:
        packet = capture_vsock_packet()
        
        # Leak 1: Packet size reveals trade size
        if packet.size > 2000:  # Large transaction
            priority = "high_value"
        
        # Leak 2: Timing reveals operation type
        start = time.time()
        response = wait_for_response()
        duration = time.time() - start
        
        if duration > 0.12:  # Swap operation
            tx_type = "swap"
        else:  # Simple transfer
            tx_type = "transfer"
        
        # Leak 3: Gas estimation
        gas_requested = packet.gas_limit
        if gas_requested > 500000:
            complexity = "high"  # DeFi interaction
        
        # FRONT-RUN THIS TRANSACTION
        if priority == "high_value" and tx_type == "swap":
            front_run(packet)
  1. The operator front-runs your trade:

  • Buys TOKEN before your transaction

  • Your transaction executes at worse price (price moved up)

  • Operator immediately sells TOKEN

  • You lose 1-3% to slippage ($10K-$30K on a $1M trade)

  • Operator pockets the difference

Real-World Example:

Flashbots relay exploitation ($25M stolen)

https://blocksec.com/blog/harvesting-mev-bots-by-exploiting-vulnerabilities-in-flashbots-relay

In October 2024, attackers exploited a Flashbots MEV-Boost relay vulnerability that exposed "greedy" MEV bot transactions before execution. One MEV bot tried to swap 2,454 WETH ($5M) for tiny profit—risk/reward ratio of 7,000:1. The attacker front-ran it, capturing the $5M trade.

This is exactly what happens when encrypted mempools leak metadata.

Another example for this type of attack is:

https://unchainedcrypto.com/mev-sandwich-bot-jared-2-0-cooks-up-new-recipes-eigenphi/

Scale: One of Ethereum's most notorious MEV bots, executing sophisticated multi-layer sandwich attacks that validate your timing and packet size metadata leakage concerns.

  • Five-layer and seven-layer sandwich attacks targeting multiple victims simultaneously

  • Advanced techniques including liquidity manipulation during sandwiches

  • Adding/removing liquidity as front-piece and back-piece of sandwiches to obfuscate profit tracking

Metadata Exploitation: The bot's sophistication demonstrates how attackers use transaction metadata (size, timing, gas estimates) to identify profitable targets before execution.

The Correct Implementation:

# CORRECT: Treat parent as adversary
class SecureEnclaveMempool:
    def process_transaction(self, encrypted_tx):
        # 1. Constant-size padding (prevents size leakage)
        padded_tx = pad_to_constant_size(encrypted_tx, 4096)
        
        # 2. Constant-time processing (prevents timing leakage)
        start_time = time.time()
        result = constant_time_validate(padded_tx)
        
        # 3. Add random delay (obscures timing)
        target_time = 0.200  # 200ms for all transactions
        elapsed = time.time() - start_time
        if elapsed < target_time:
            time.sleep(target_time - elapsed)
        
        # 4. Generic responses only (prevents error leakage)
        if result.valid:
            return generic_success()
        else:
            # Don't reveal WHY it failed
            log_internally(result.error)  # Only internal logging
            return generic_error()
        
        # 5. Batch processing (prevents individual tx identification)
        self.batch_buffer.append(encrypted_tx)
        if len(self.batch_buffer) >= 100:
            process_batch(self.batch_buffer)

Threat 9: Bridge and Validator Key Compromise

Hardcoded Private Keys in EIF

Affected Protocols: Cross-chain bridges, validator nodes, any system with persistent signing keys

The Promise: "Bridge keys secured in TEE. Funds are safe."

The Problem: Developer embeds private key directly in the EIF file.

Simple Scenario:

A cross-chain bridge holds 10,000 BTC ($600M at $60K/BTC). The bridge uses a TEE-based validator to sign withdrawal transactions.

# Dockerfile for bridge validator - WRONG
FROM ubuntu:22.04

# Install dependencies
RUN apt-get update && apt-get install -y python3

# Copy bridge application
COPY bridge_validator.py /app/
COPY requirements.txt /app/

# FUCKUP: Hardcode the private key
ENV BRIDGE_PRIVATE_KEY="5Kb8kLf2dN9qWxE3gYpRjCvXt7sUyQ1mP..."

CMD ["python3", "/app/bridge_validator.py"]

The nitro-cli converts this to an EIF:

nitro-cli build-enclave --docker-uri bridge-validator:latest --output-file bridge.eif

The EIF now contains the private key in the ramdisk section..

Attacker’s Process:

# Step 1: Get access to EC2 instance (many ways)
# - SSH key compromise
# - IAM credential leak
# - Insider threat
# - EC2 metadata service exploit

# Step 2: Download the EIF
aws s3 cp s3://bridge-artifacts/bridge.eif .

# Step 3: Extract EIF contents
# EIF is just a file with known structure
python3 extract_eif.py bridge.eif

# Output:
# - kernel.img (Linux kernel)
# - ramdisk0.cpio (bootstrap)
# - ramdisk1.cpio (application)

# Step 4: Extract ramdisk
cpio -idv < ramdisk1.cpio

# Step 5: Search for secrets
grep -r "BRIDGE_PRIVATE_KEY" .
# Found: ./app/docker-env
# BRIDGE_PRIVATE_KEY=5Kb8kLf2dN9qWxE3gYpRjCvXt7sUyQ1mP...

# Step 6: Use the key
python3 drain_bridge.py --key 5Kb8kLf2dN9qWxE3gYpRjCvXt7sUyQ1mP...

The attacker now has the bridge's private key and can:

  1. Sign withdrawal transactions for the full 10,000 BTC

  2. Send to their own addresses

  3. Drain the entire bridge: $600M stolen

Real-World Example: Ronin Bridge Hack ($625M)

In March 2022, attackers stole 173,600 ETH + 25.5M USDC ($625M total) from Ronin Bridge by compromising validator keys. While not a TEE attack, this shows the catastrophic impact of key compromise on bridges.

If those keys had been "secured" in a TEE but leaked via hardcoded EIF storage, the attack would have been even easier.

Threat 10: Oracle and Price Feed Manipulation

KMS MitM Injects Fake Price Data

Affected Protocols: TEE-based oracles (Chainlink-style with TEEs), price feed aggregators, any system fetching external data via KMS

The Promise: "Price data secured end-to-end in TEE. Manipulation impossible."

The Problem: Using KMS Setup 1 without authenticating responses.

Simple Scenario:

A DeFi lending protocol uses a TEE-based oracle to fetch asset prices. The protocol has $500M TVL with:

  • $300M in ETH collateral

  • $200M in stablecoin debt

When ETH price drops below threshold, positions get liquidated.

Attack Flow:

  1. Oracle requests ETH price from KMS

  2. Parent intercepts the request

  3. Parent sees the public RSA key in the attestation

  4. Parent generates FAKE encrypted response

  5. Oracle receives fake price ($1,500 instead of $2,000)

  6. Lending protocol thinks ETH crashed by 25%

  7. Protocol liquidates $100M+ in healthy positions

  8. Attacker (who controls the parent) positioned to profit:

    • Already bought liquidated collateral at discount

    • Already shorted ETH on other exchanges

    • Profits $20-50M from the manipulated liquidations

Real-World Impact: Compound Finance Vulnerability

In 2020, Compound had a price oracle manipulation vulnerability (not TEE-related, but same principle). An attacker could have manipulated DAI price oracle to liquidate $100M+ in collateral. Fortunately discovered before exploitation[web3 history].

With TEE-based oracles using Setup 1, this attack becomes trivially easy for anyone with parent instance access.

Conclusion: The Web3 TEE Security Crisis

Every attack follows the same flow:

  1. Developer trusts something they shouldn't (parent, metadata, timing, error messages)

  2. TEE hardware works perfectly (isolation, encryption, attestation all function)

  3. Implementation leaks data through side channels (vsock metadata, timing, crashes, errors)

  4. Attacker exploits leaked data for immediate financial gain

  5. Blockchain immutability makes it permanent and irreversible

The Uncomfortable Truth:

Most Web3 projects using TEEs today have at least 3-5 of these vulnerabilities. They just haven't been exploited yet.

The security community knows this. Attackers know this. It's only a matter of time before someone automates the scanning and exploits them all.

Last updated