惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
NISL@THU
NISL@THU
S
Secure Thoughts
P
Palo Alto Networks Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
AWS News Blog
AWS News Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
S
Security @ Cisco Blogs
Cloudbric
Cloudbric
L
LINUX DO - 最新话题
L
LINUX DO - 热门话题
O
OpenAI News
C
Cyber Attacks, Cyber Crime and Cyber Security
Google DeepMind News
Google DeepMind News
Schneier on Security
Schneier on Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
www.infosecurity-magazine.com
www.infosecurity-magazine.com
月光博客
月光博客
阮一峰的网络日志
阮一峰的网络日志
Forbes - Security
Forbes - Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
Securelist
S
Security Affairs
博客园 - 三生石上(FineUI控件)
V2EX - 技术
V2EX - 技术
Apple Machine Learning Research
Apple Machine Learning Research
D
Darknet – Hacking Tools, Hacker News & Cyber Security
人人都是产品经理
人人都是产品经理
IT之家
IT之家
T
Threat Research - Cisco Blogs
博客园 - 司徒正美
J
Java Code Geeks
C
Cisco Blogs
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
W
WeLiveSecurity
N
News and Events Feed by Topic
P
Privacy International News Feed
V
Visual Studio Blog
博客园_首页
量子位
C
Cybersecurity and Infrastructure Security Agency CISA
Y
Y Combinator Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
The Exploit Database - CXSecurity.com
Security Archives - TechRepublic
Security Archives - TechRepublic
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
N
News and Events Feed by Topic
D
DataBreaches.Net
The Cloudflare Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Apple Fixes the iPhone Bug That Cops Used to Extract Your Deleted Messages
佐藤玲 · 2026-04-23 · via DEV Community

Apple Fixes the iPhone Bug That Cops Used to Extract Your Deleted Messages

If you've ever deleted a sensitive message and assumed it was gone forever — think again. For years, a quiet vulnerability in iOS allowed forensic tools used by law enforcement to recover deleted iMessages, WhatsApp chats, and other communications from iPhones. Apple has now fixed that bug, but the story behind it reveals something every developer, security engineer, and privacy-conscious user needs to understand about how "deleted" data actually works at the filesystem level.

Let's break it down.


What Was the Bug?

The vulnerability existed in how iOS handled SQLite database vacuuming — or more precisely, how it didn't handle it. Most messaging apps on iOS, including Apple's own iMessage, store conversation history in SQLite databases on the device. When you delete a message, the app marks those database rows as deleted, but the underlying data isn't always immediately overwritten.

In standard SQLite behavior, deleted rows leave behind what's called free pages — sectors of storage that are marked available for reuse but still contain the old data until something else writes over them. iOS was not aggressively reclaiming or zeroing out this space, which meant forensic tools could:

  1. Image the raw NAND flash storage (via physical extraction or exploits)
  2. Parse the SQLite .db files directly
  3. Recover rows from free pages that iOS considered "deleted"

Tools like Cellebrite UFED and GrayKey — which are commercially sold almost exclusively to law enforcement agencies — that cops used routinely to extract this data from seized iPhones.


How SQLite Deletion Actually Works (The Developer View)

This is worth understanding at a deeper level if you build apps that handle sensitive data.

When SQLite deletes a row, it doesn't zero the memory. It marks the page as free in the database's internal free-list. Here's a minimal example:

-- Create a simple messages table
CREATE TABLE messages (
  id INTEGER PRIMARY KEY,
  sender TEXT,
  content TEXT,
  timestamp INTEGER
);

-- Insert some data
INSERT INTO messages VALUES (1, 'Alice', 'Meet me at 9pm', 1700000000);
INSERT INTO messages VALUES (2, 'Bob', 'Bring the documents', 1700000100);

-- "Delete" a message
DELETE FROM messages WHERE id = 1;

-- The row is logically gone, but the page may still contain raw data
-- until VACUUM is run or the page is reused

Enter fullscreen mode Exit fullscreen mode

To actually reclaim and zero that space, you need to run:

VACUUM;

Enter fullscreen mode Exit fullscreen mode

Or enable auto-vacuum at database creation:

PRAGMA auto_vacuum = FULL;

Enter fullscreen mode Exit fullscreen mode

Apple's fix essentially ensures iOS enforces more aggressive vacuuming and page zeroing on sensitive app databases — particularly for system-level apps like iMessage — so that deleted content doesn't linger in recoverable free pages.


What Did the Fix Actually Change?

According to security researchers who analyzed the patch (included in iOS 17.4 and backported to iOS 16), Apple made several changes:

1. Forced VACUUM on Message Deletion

The Messages app now triggers a VACUUM or equivalent wipe operation when messages are deleted, rather than relying on passive page reuse.

2. Secure Enclave-Tied Encryption Keys Rotated More Aggressively

Apple tightened how encryption keys tied to message databases are rotated after deletion events. Even if raw pages were somehow extracted, they'd be encrypted with keys that no longer exist on the device.

3. Reduced Forensic Tool Surface Area

The patch addresses specific entrypoints that third-party forensic extraction tools relied on — including certain AFC (Apple File Connection) protocol behaviors that allowed deeper filesystem reads than intended.


Why This Matters for Developers

If you're building an iOS app that handles any sensitive user data — health records, financial information, private messages, authentication tokens — this bug should be a wake-up call.

Here are the lessons to take away:

Don't Trust App-Level Deletion Alone

Calling context.delete(object) in Core Data or DELETE FROM table in SQLite does not guarantee the data is unrecoverable. You need to explicitly handle secure deletion.

// Example: Forcing a SQLite VACUUM in Swift after sensitive deletion
import SQLite3

func securePurgeDatabase(dbPath: String) {
    var db: OpaquePointer?

    guard sqlite3_open(dbPath, &db) == SQLITE_OK else {
        print("Failed to open database")
        return
    }

    defer { sqlite3_close(db) }

    let vacuumQuery = "VACUUM;"
    var errMsg: UnsafeMutablePointer<Int8>?

    if sqlite3_exec(db, vacuumQuery, nil, nil, &errMsg) != SQLITE_OK {
        let errorMessage = String(cString: errMsg!)
        print("VACUUM failed: \(errorMessage)")
        sqlite3_free(errMsg)
    } else {
        print("Database securely vacuumed.")
    }
}

Enter fullscreen mode Exit fullscreen mode

Use the Data Protection API Correctly

Apple's Data Protection API provides four protection classes. Most developers default to .completeUntilFirstUserAuthentication, but for truly sensitive data you should use .complete:

// Setting file protection on a sensitive database file
let fileURL = URL(fileURLWithPath: dbPath)

try FileManager.default.setAttributes(
    [.protectionKey: FileProtectionType.complete],
    ofItemAtPath: fileURL.path
)

Enter fullscreen mode Exit fullscreen mode

With .complete, the file is encrypted and inaccessible whenever the device is locked — dramatically reducing the window for forensic extraction.

Consider Using Encrypted Database Libraries

For apps with high security requirements, consider replacing plain SQLite with SQLCipher for iOS — an open-source extension that provides transparent 256-bit AES encryption of SQLite databases. Even if raw pages are extracted, they're meaningless without the key.

// SQLCipher integration example (via CocoaPods: pod 'SQLCipher')
// Opening an encrypted database
var db: OpaquePointer?
sqlite3_open(dbPath, &db)

let key = "your-secure-derived-key"
sqlcipher_export(db, key) // Encrypts the entire database

Enter fullscreen mode Exit fullscreen mode


The Bigger Picture: Law Enforcement, Privacy, and Platform Power

This fix quietly resolves something that has been a known capability in law enforcement circles for years. The forensic tools that cops used to extract deleted messages weren't exploiting some zero-day — they were leveraging predictable, documented behavior of SQLite and iOS's relatively passive approach to data cleanup.

What's interesting from a policy perspective:

  • Apple knew this behavior existed — it's inherent to how SQLite works
  • Law enforcement agencies paid tens of thousands of dollars for tools like Cellebrite specifically because this data was recoverable
  • The fix came quietly — no CVE number was prominently announced, no dramatic security advisory. It was patched as part of a broader update.

This raises a question developers and security engineers should sit with: How many other "expected behaviors" in the platforms we build on are actually silent privacy vulnerabilities?


What Should Users Do Right Now?

If you're not a developer and you stumbled into this article:

  • Update to iOS 17.4 or later immediately. The fix is there, but only if you install it.
  • Enable full device encryption (it's on by default with a passcode, but verify in Settings → Face ID & Passcode).
  • If you use a third-party messaging app, check whether they have their own secure deletion implementations. Signal, for example, has always been more aggressive about this.

Developer Checklist: Secure Data Deletion on iOS

Here's a quick reference checklist for any iOS app handling sensitive data:

  • [ ] Use FileProtectionType.complete for sensitive files at rest
  • [ ] Run VACUUM or enable auto_vacuum = FULL after bulk deletions in SQLite
  • [ ] Consider SQLCipher or encrypted storage solutions for high-sensitivity apps
  • [ ] Rotate or destroy encryption keys when data is deleted (use Keychain with appropriate accessibility flags)
  • [ ] Test with forensic tools in your own QA process — yes, some are available for research use
  • [ ] Never store sensitive plaintext in UserDefaults
  • [ ] Implement secure memory wiping for in-memory sensitive strings (avoid Swift String for passwords; use Data that can be zeroed)
// Zeroing sensitive data in memory
var sensitiveBytes = [UInt8](repeating: 0, count: 32)
// ... use sensitiveBytes ...
// Zero out before release
memset_s(&sensitiveBytes, sensitiveBytes.count, 0, sensitiveBytes.count)

Enter fullscreen mode Exit fullscreen mode


Final Thoughts

The fact that Apple fixes this particular behavior is a win for privacy — but it took years and significant real-world exploitation before it happened. As developers, we can't always wait for platform vendors to close gaps that affect our users.

Understand your data lifecycle. Know what "deleted" means at every layer of your stack — from your app's data model down to the raw filesystem. Treat deletion as a security operation, not just a UI event.

The tools law enforcement used to extract these messages weren't magic. They were the predictable result of trusting that app-level deletion equals data destruction. It doesn't. Now you know.


If this breakdown was useful, follow me here on DEV for more deep-dives into iOS security, privacy engineering, and mobile development best practices. Drop a comment below if you want a follow-up post on implementing full secure deletion pipelines in iOS apps.