Mail Attachment Metadata
Overview
Apple Mail tracks email attachment metadata in two locations: the Envelope Index SQLite database contains a lightweight attachments table with filenames and identifiers, while the EMLX files themselves contain full MIME structures from which attachment content types and sizes can be extracted. Together, these sources provide comprehensive evidence of file transfers via email without requiring the actual attachment files to be collected.
Attachment metadata is forensically significant for identifying file transfers, potential data exfiltration, malware delivery, and evidence of document exchange between parties.
File Locations
| Source | Path | Format |
|---|---|---|
| Envelope Index attachments | ~/Library/Mail/V{N}/MailData/Envelope Index | SQLite (attachments table) |
| EMLX MIME parts | ~/Library/Mail/V{N}/{UUID}/*.mbox/**/*.emlx | Embedded in MIME structure |
| Opened attachments log | ~/Library/Mail/V{N}/MailData/OpenedAttachmentsV2.plist | Plist |
Database Schema
Envelope Index: attachments Table
CREATE TABLE attachments (
ROWID INTEGER PRIMARY KEY AUTOINCREMENT,
message INTEGER NOT NULL REFERENCES messages(ROWID) ON DELETE CASCADE,
attachment_id TEXT COLLATE BINARY, -- Internal attachment identifier
name TEXT COLLATE BINARY, -- Original filename
UNIQUE(message, attachment_id)
);
Each row represents one attachment for a specific message. The message column is a foreign key to messages.ROWID.
EMLX MIME Attachment Metadata
Within EMLX files, attachments appear as MIME parts with:
| MIME Header | Example | Purpose |
|---|---|---|
Content-Type | application/pdf; name="report.pdf" | MIME type and filename |
Content-Disposition | attachment; filename="report.pdf" | Disposition and filename |
Content-Transfer-Encoding | base64 | How the content is encoded |
The filename can appear in either the Content-Type name parameter or the Content-Disposition filename parameter. Both should be checked, with Content-Disposition taking precedence.
Key Fields for Analysis
From Envelope Index
| Column | Forensic Significance |
|---|---|
attachments.name | Original filename of the attachment |
attachments.attachment_id | Internal identifier for the attachment |
attachments.message | FK to the parent message |
From EMLX MIME Parts
| Field | Forensic Significance |
|---|---|
| Filename | Original name as sent by the sender |
| Content-Type | File type (e.g., application/pdf, image/jpeg) |
| Size | Decoded content length in bytes |
Forensic Queries
-- All messages with attachments
SELECT
m.ROWID,
datetime(m.date_received, 'unixepoch') AS received_utc,
a_addr.address AS sender,
s.subject,
att.name AS attachment_name,
att.attachment_id
FROM messages m
JOIN attachments att ON att.message = m.ROWID
LEFT JOIN addresses a_addr ON m.sender = a_addr.ROWID
LEFT JOIN subjects s ON m.subject = s.ROWID
ORDER BY m.date_received DESC;
-- Count attachments per sender
SELECT
a_addr.address AS sender,
COUNT(att.ROWID) AS attachment_count
FROM messages m
JOIN attachments att ON att.message = m.ROWID
JOIN addresses a_addr ON m.sender = a_addr.ROWID
GROUP BY a_addr.address
ORDER BY attachment_count DESC;
-- Attachment file types (by extension)
SELECT
LOWER(SUBSTR(name, INSTR(name, '.') + 1)) AS extension,
COUNT(*) AS count
FROM attachments
WHERE name LIKE '%.%'
GROUP BY extension
ORDER BY count DESC;
OpenedAttachmentsV2.plist
The OpenedAttachmentsV2.plist file records which attachments the user has explicitly opened from within Mail.app. Each entry typically includes:
- The attachment filename
- The message it was associated with
- The timestamp of when it was opened
This plist provides direct evidence that the user interacted with a specific attachment, going beyond simply receiving the email.
Timestamps
The Envelope Index attachments table does not contain its own timestamps. The parent message's date_received and date_sent timestamps (Unix epoch seconds) provide temporal context.
The OpenedAttachmentsV2.plist contains its own timestamps for when attachments were opened.
Analysis Notes
- Envelope Index vs EMLX: The Envelope Index
attachmentstable provides quick access to attachment filenames and counts. For detailed metadata (MIME type, size, encoding), the EMLX file's MIME structure must be parsed. - Filename as evidence: The
namecolumn contains the filename as sent by the sender. This may differ from how the file was saved locally. Common file types of forensic interest include.pdf,.docx,.xlsx,.zip,.exe, and image formats. - Missing attachment content: macfor collects attachment metadata only. The actual attachment binary content is embedded in the EMLX file's MIME parts (typically base64-encoded). Full attachment extraction requires EMLX parsing with MIME decoding.
- Inline vs attached: MIME parts with
Content-Disposition: inlineare displayed within the email body (e.g., embedded images) rather than as downloadable files. Both inline and attached content appear in the MIME structure. - Data exfiltration indicators: Patterns to look for include large attachments sent to external addresses, encrypted file types (
.pgp,.gpg), or archive formats (.zip,.rar,.7z) sent at unusual times. - Opened attachments plist: The
OpenedAttachmentsV2.plistis particularly valuable because it proves user awareness of and interaction with specific files. A received email attachment that was never opened tells a different story than one that was opened multiple times.
Version Differences
| macOS Version | Changes |
|---|---|
| 10.15+ | Stable attachments table schema |
| All versions | MIME part structure governed by email standards, not macOS version |
Tool Support
| Tool | Capability |
|---|---|
| macfor | Collects attachment metadata from both Envelope Index and EMLX MIME parts |
| sqlite3 CLI | Query Envelope Index attachments table |
| plutil / plistutil | Read OpenedAttachmentsV2.plist |