# Cloudflare Containers Cross-Tenant Data Exposure via Unzeroed Reused Storage Blocks (skip_block_zeroing)

> A cross-tenant data exposure flaw in Cloudflare Containers and Sandboxes (Workers Paid plan) let one customer recover residual disk data left behind by a different tenant's deleted container, because the shared dm-thin storage pool was configured with skip_block_zeroing and skipped clearing reused 64 KiB blocks. Security researcher Oren Yomtov of Accomplish responsibly disclosed the issue via HackerOne on September 4, 2026; Cloudflare merged a runtime fix within six hours, awarded the bounty within ten days, and completed fleet-wide remediation by September 19, 2026, finding no evidence of exploitation by anyone other than the reporting researcher and Cloudflare's own validation.

- **Published:** 2026-09-27T00:00:00Z
- **Last reviewed:** 2026-09-27T00:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-2698
- **Card image:** https://intel.threadlinqs.com/og/threat/threat-intel-cloudflare-containers-data-leak-tl-2026-2698.webp?v=a119b9f5 (Threadlinqs threat intel: Cloudflare Containers Disk Exposure: Detection & IOCs (TL-2026-2698) — High severity, 12 IOCs, 9 detection rules.)
- **ID:** TL-2026-2698
- **Severity:** HIGH
- **Category:** VULNERABILITY
- **Status:** PATCHED
- **Detections:** 9 (1 shown free below) · **IOCs:** 12

## Description

Cloudflare Containers and the Sandbox SDK built on top of them run each customer workload in a dedicated Firecracker microVM whose root disk is presented to the guest as a writable block device (/dev/vdc). Storage for these disks is provisioned from shared pools using Linux device-mapper thin provisioning (dm-thin) with a 64 KiB thin-block size, which normally zeroes a newly allocated block before exposing it to a tenant. Cloudflare's pools were configured with the dm-thin feature argument skip_block_zeroing, which per the kernel's own documentation "skips zeroing newly allocated blocks before making them accessible" -- a setting chosen for allocation-latency performance that instead created a cross-tenant exposure.

Because thin-provisioned blocks are allocated in 64 KiB units while filesystem writes can be much smaller, a 4 KiB write into a previously unmapped, 64 KiB-aligned free region of an ext4 filesystem was enough to trigger dm-thin to hand back a physical block that a prior tenant's deleted container had used -- physical blocks return to the shared pool, serving multiple customer accounts, once a thin volume is deleted. Only the 4 KiB actually written was overwritten; the remaining 60 KiB of the block could still contain that prior tenant's bytes. A subsequent raw read of the underlying block device recovered this residual data without needing to target any specific customer or workload -- any Workers Paid account with Containers/Sandboxes access could probe for it, though Cloudflare's automatic, randomized workload placement meant an attacker could not choose a victim, host, workload, or specific piece of information in advance.

Researcher Oren Yomtov (Accomplish) validated the technique across production placements on four continents: of 24 container placements tested across 22 underlying nodes, 18 placements on 20 nodes returned residual foreign material, including directory structures and ext4 metadata (identifiable via the filesystem's metadata_csum directory-block checksums), database pages, structurally complete SQLite databases, Chromium browser profile data, .env files, and other credential-bearing files. Across a subset of six production placements the researcher's tooling examined 5,614 testable directory blocks and identified 2,700 distinct foreign directory inodes; per Cloudflare, the validation scripts only returned aggregate counts rather than exfiltrating actual file contents, and any recovered data was securely deleted after submission consistent with Cloudflare's HackerOne disclosure policy. A separate control set of 162 deliberately-created test blocks was later used to confirm the corrected dm-thin behavior actually zeroed new allocations post-fix.

Cloudflare additionally confirmed that its Browser Rendering product's Browser Run service shared the same affected dm-thin storage pools. Cloudflare's response timeline was compressed: the report landed at 15:26 UTC on September 4, the production flaw was confirmed at 18:45 UTC, a runtime fix removing skip_block_zeroing was merged at 21:27 UTC, an accompanying pool-configuration change merged at 22:03 UTC, and fleet-wide rollout began at 23:15 UTC the same day -- all within roughly eight hours of the initial report. Rollout completed September 7 at 06:13 UTC, after which Cloudflare began clearing pre-mitigation data: retiring and recreating all running container root disks that predated the fix (forcing zeroed allocation going forward), deleting cached OCI image-layer snapshots created before the change, and draining affected hosts during off-peak windows to restart VMs and clear image caches. The researcher's proof-of-concept was confirmed non-functional against the patched fleet on September 14 at 10:50 UTC, and the HackerOne bounty was awarded roughly two hours later at 12:52 UTC. All pre-mitigation disk and image-layer snapshots were removed fleet-wide by September 19 at 15:03 UTC, completing full remediation. As a defensive follow-up, Cloudflare also built detection signatures around the attack's distinctive disk-I/O fingerprint -- a small (~4 KiB) write immediately followed by a disproportionately large raw read from a newly allocated 64 KiB block -- and reviewed historical disk-I/O telemetry fleet-wide, attributing all anomalous access patterns solely to the reporting researcher and Cloudflare's own authorized validation. Cloudflare concluded there is no evidence any other party exploited the flaw or that customer data was compromised. No CVE has been assigned and Cloudflare did not publish a CVSS score; this is a storage-layer data-remanence bug, not a container, hypervisor, or Firecracker VM escape.

## MITRE ATT&CK

- T1595.002 Vulnerability Scanning
- T1587.004 Develop Capabilities: Exploits
- T1078.004 Valid Accounts: Cloud Accounts
- T1059 Command and Scripting Interpreter
- T1580 Cloud Infrastructure Discovery
- T1082 System Information Discovery
- T1005 Data from Local System
- T1213 Data from Information Repositories
- T1119 Automated Collection
- T1552.001 Credentials In Files
- T1555.003 Credentials from Web Browsers

## Free detection (Splunk SPL, Microsoft KQL, Sigma)

**Credential-Bearing File Access Following Raw Block Device Read (Residual Data Harvesting) — SPL** (`TL-2026-2698-SPL-002`)

Detects post-exploitation harvesting of credential-bearing artifacts recovered from residual dm-thin storage blocks: a process that opens a raw block device path and, within a short window, also opens a .env file, a SQLite database, or a Chromium profile artifact ("Login Data"/"Cookies"). Cloudflare's researcher recovered structurally complete SQLite databases, Chromium profile data, and .env files directly from unzeroed reused blocks belonging to other tenants.

- **Languages:** Splunk SPL, Microsoft KQL, Sigma
- **ATT&CK:** T1552.001, T1555.003, T1213, T1119
- **Data sources:** linux_auditd (SYSCALL/PATH records), sysmon_for_linux (FileCreate/RawAccessRead), microsoft_defender_for_endpoint_linux (DeviceFileEvents)
- **Severity:** critical
- **Confidence:** medium

### Splunk SPL

```spl
index=linux_audit sourcetype="auditd" (type=SYSCALL OR type=PATH)
| eval target=coalesce(name, path)
| eval event_class=case(
    match(target, "^/dev/(vd[a-z]+|dm-[0-9]+|mapper/.+)$"), "rawdev_access",
    match(target, "(?i)\.env$"), "credfile_env",
    match(target, "(?i)\.(sqlite|db)$"), "credfile_sqlite",
    match(target, "(?i)(Login Data|Cookies)$"), "credfile_browser",
    1=1, null())
| where isnotnull(event_class)
| bin _time span=2m
| stats values(event_class) as event_classes values(target) as targets earliest(_time) as first_ts latest(_time) as last_ts by _time, exe, pid, user
| where mvfind(event_classes,"rawdev_access")>=0 AND (mvfind(event_classes,"credfile_env")>=0 OR mvfind(event_classes,"credfile_sqlite")>=0 OR mvfind(event_classes,"credfile_browser")>=0)
| table first_ts last_ts exe pid user targets
| sort - last_ts
```

### Microsoft KQL

```kql
let lookback = 24h;
let rawDevAccess = DeviceFileEvents
| where Timestamp > ago(lookback)
| where FolderPath matches regex @"^/dev/(vd[a-z]+|dm-\d+|mapper/.+)$"
| project Timestamp, DeviceId, Account = InitiatingProcessAccountName, InitiatingProcessId, Process = InitiatingProcessFileName, RawDevPath = FolderPath;
let credFileAccess = DeviceFileEvents
| where Timestamp > ago(lookback)
| where FileName has_any (".env", ".sqlite", ".db") or FileName in ("Login Data", "Cookies")
| project Timestamp, DeviceId, InitiatingProcessId, CredFile = FileName;
rawDevAccess
| join kind=inner (credFileAccess) on DeviceId, InitiatingProcessId
| where abs(datetime_diff('second', Timestamp, Timestamp1)) <= 120
| project FirstSeen = Timestamp, SecondSeen = Timestamp1, DeviceId, Account, Process, RawDevPath, CredFile
| order by SecondSeen desc
```

### Sigma

```yaml
title: Non-Standard Process Access to Credential-Bearing Files Consistent with Residual Disk-Block Harvesting
id: b1c4d7e0-2a5f-4c8b-9d1e-6f3a0b7c2d4e
status: experimental
description: Detects generic file-read/scripting utilities (cat, dd, python, hexdump, strings) opening credential-bearing artifacts (.env files, SQLite databases, or Chromium "Login Data"/"Cookies" profile files) outside their normal owning application context, consistent with harvesting residual data recovered via the Cloudflare Containers dm-thin skip_block_zeroing cross-tenant exposure.
references:
    - https://blog.cloudflare.com/containers-cross-tenant-vulnerability/
author: Threadlinqs Team
date: 2026-09-27
tags:
    - attack.credential_access
    - attack.t1552.001
    - attack.t1555.003
    - attack.collection
    - attack.t1213
    - attack.t1119
logsource:
    category: file_event
    product: linux
detection:
    sel_proc:
        Image|endswith:
            - '/cat'
            - '/dd'
            - '/python3'
            - '/python'
            - '/hexdump'
            - '/strings'
    sel_target:
        TargetFilename|endswith:
            - '.env'
            - '.sqlite'
            - '.db'
    sel_target_browser:
        TargetFilename|contains:
            - 'Login Data'
            - 'Cookies'
    condition: sel_proc and (sel_target or sel_target_browser)
falsepositives:
    - Application startup, backup, or CI/test tooling legitimately reading these files with a generic utility
    - Developers debugging locally with cat/hexdump against their own .env or SQLite files
level: medium
```

**Known false positives:**

- Backup, DLP-scanning, or CI/test pipelines that legitimately enumerate both raw devices and credential-style files in the same job
- Container image build systems reading .env/SQLite fixtures during automated tests

**Tuning notes:** Exclude known backup/DLP/CI service accounts and their scheduled job windows; require the rawdev_access target to match the environment's specific container-root-disk naming convention rather than any block device; extend the 2-minute correlation window only if the platform's own storage layer shows higher I/O latency.

### 8 more detection rules (Splunk SPL, Microsoft KQL, Sigma), unlock with TL Creds

- Raw Block Device Small-Write-Then-Large-Read Fingerprint (dm-thin Residual Data Probe) — KQL (locked: unlock with TL Creds)
- Credential-Bearing File Access Following Raw Block Device Read (Residual Data Harvesting) — KQL (locked: unlock with TL Creds)
- Cross-Placement Container/Sandbox API Enumeration Indicative of Cross-Tenant Storage Probing — KQL (locked: unlock with TL Creds)
- Raw Block Device Read Following Small Aligned Write (dm-thin Residual Data Probe) — Sigma (locked: unlock with TL Creds)
- Non-Standard Process Access to Credential-Bearing Files Consistent with Residual Disk-Block Harvesting — Sigma (locked: unlock with TL Creds)
- High-Volume Cross-Placement Container/Sandbox Enumeration via Cloud API (Cross-Tenant Storage Probing) — Sigma (locked: unlock with TL Creds)
- Raw Block Device Small-Write-Then-Large-Read Fingerprint (dm-thin Residual Data Probe) — SPL (locked: unlock with TL Creds)
- Cross-Placement Container/Sandbox API Enumeration Indicative of Cross-Tenant Storage Probing — SPL (locked: unlock with TL Creds)

Sign up free to unlock the detection rules: https://threadlinqs.com/?modal=signup

## Sources

- [How Cloudflare addressed a cross-tenant data exposure vulnerability in Containers](https://blog.cloudflare.com/containers-cross-tenant-vulnerability/)
- [Cloudflare fixes Containers cross-tenant flaw exposing customer data](https://www.bleepingcomputer.com/news/security/cloudflare-fixes-containers-cross-tenant-flaw-exposing-customer-data/)
- [Cloudflare Containers Vulnerability Could Leak Data Between Customer Workloads](https://cybersecuritynews.com/cloudflare-containers-vulnerability/)
- [Cloudflare Containers Flaw Could Expose Data From Other Customers' Workloads](https://gbhackers.com/cloudflare-containers-flaw/)
- [Cloudflare Fixes Cross-Tenant Data Exposure Bug in Containers](https://www.technadu.com/cloudflare-fixes-cross-tenant-data-exposure-bug-in-containers/638675/)
- [Cloudflare Containers Cross-Tenant Disk Exposure: What Was Affected and How It Was Fixed](https://aicybr.com/blog/cloudflare-containers-cross-tenant-residual-disk-exposure)
- [Cloudflare Containers Flaw Leaked Data on 18 Hosts](https://shattered.io/cloudflare-containers-flaw-18-hosts-2026/)
- [Thin provisioning — The Linux Kernel documentation (device-mapper dm-thin, skip_block_zeroing)](https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/thin-provisioning.html)
- [Containers and Sandboxes are now generally available](https://developers.cloudflare.com/changelog/post/2026-04-13-containers-sandbox-ga/)

## Full data

The other 8 detection rules (Splunk SPL / Microsoft KQL / Sigma) unlock with TL Creds; a free account includes daily creds: https://threadlinqs.com/?modal=signup
Indicator values unlock with TL Creds, at a lower price on Red and Purple; AI agents can query rules and IOCs through the Threadlinqs MCP server (Purple): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-2698
