kMDItemWhereFroms vs the macOS Quarantine Attribute
Where did this file come from on a Mac? Read kMDItemWhereFroms, compare it with quarantine data, and interpret a missing quarantine attribute.
TL;DR. kMDItemWhereFroms is an extended attribute holding a binary property list of strings, usually the download URL and the referring page (for Mail, sender and subject-like strings). It answers "where did this file come from?" but, unlike the quarantine attribute and the QuarantineEventsV2 database, it carries no flags, no agent and no UUID. A file that still has WhereFroms but has lost its quarantine attribute is a useful lead, not proof of tampering.
What kMDItemWhereFroms holds
The full attribute name is com.apple.metadata:kMDItemWhereFroms. Browsers and Mail set it when they save a file. Its value is a binary property list containing an array of strings:
- for a browser download, usually the download URL followed by the referrer or page it was started from;
- for a Mail attachment, sender and subject-like strings.
It sits on the file itself, next to com.apple.quarantine. The glossary entry on kMDItemWhereFroms gives the short definition.
How to read it
With mdls
On a live system, Spotlight exposes the value directly:
mdls -name kMDItemWhereFroms ~/Downloads/report.pdf
mdls asks Spotlight, so it works on the running Mac for files that Spotlight has indexed. For collected evidence, read the attribute itself.
With xattr
xattr -p com.apple.metadata:kMDItemWhereFroms ~/Downloads/report.pdf
xattr -l -x ~/Downloads/report.pdf
The first command prints the value as text. Because the value is a binary property list, that output looks garbled: the URL strings are readable, but they are interleaved with length and type bytes that do not render. xattr -l without -x has the same problem. The second command prints every attribute as a hex dump, which preserves the exact bytes.
For a folder tree, use the listing from the collection guide:
xattr -r -l -x ~/Downloads ~/Desktop ~/Documents ~/Library/LaunchAgents > ~/qcase/xattr_$(id -un).txt 2>/dev/null
Quarantine Parser decodes WhereFroms from hex listings exactly. From a plain text rendering it can only decode it approximately, because bytes may have been lost on the way to the terminal. If you have the choice, collect with -x.
Three records, three different questions
WhereFroms, the quarantine attribute and the database overlap, but each proves something different.
| kMDItemWhereFroms | com.apple.quarantine | QuarantineEventsV2 | |
|---|---|---|---|
| Where | Extended attribute on the file | Extended attribute on the file | Per-user SQLite database |
| Content | URL and referrer; Mail sender and subject-like strings | Flags, hex Unix time, agent name, UUID | Time, agent, bundle ID, data and origin URLs, sender, type number |
| Tells you | Which URL or message the file was saved from | That the file was marked for Gatekeeper, when, by which app, and whether it was approved | That a quarantined download happened; no local file path or name |
| Survives deletion of the file | No | No | Rows typically persist |
| Removable | Yes, like any extended attribute | Yes: xattr -d com.apple.quarantine or xattr -c | Rows with sqlite3, or the whole file |
The UUID in the quarantine value is what joins the file to its database row; see the flags guide. WhereFroms has no such key, so any link between a WhereFroms value and a database row relies on matching URLs and times. Also remember that many real rows have empty URL columns, and that tools such as curl, wget, scp, rsync or git do not opt in to quarantine at all.
The "WhereFroms but no quarantine" pattern
Quarantine Parser raises a finding when a file carries WhereFroms but no quarantine attribute, worded as "possible xattr -d". The reasoning: a browser that writes WhereFroms normally also leaves a quarantine attribute, and xattr -d com.apple.quarantine removes the latter without touching the former, or the database.
That explanation is plausible, especially for executables where removing quarantine skips Gatekeeper. Before writing it down as anti-forensics, consider alternatives:
- Partial attribute copies. A copy, sync or transfer path may have preserved some extended attributes and not others. Behaviour depends on the tool and the file systems involved.
- Extraction by other tools. Archive Utility propagates the archive's quarantine value to extracted files; third-party unarchivers may not. What they do with other attributes is tool-specific.
- Whole-attribute clearing is different.
xattr -cremoves all attributes, WhereFroms included, so it does not produce this pattern.
Test the specific tool and macOS version where you can, and look for corroboration: a database row whose URL matches the WhereFroms, or a row recovered from free space.
AppleDouble: attributes that travel
Extended attributes can outlive the original file when they travel with a copy.
._ files on exFAT, FAT and SMB
On file systems without extended attributes, macOS writes an AppleDouble companion named ._<name> that holds the attributes. When a user copies a downloaded file to an exFAT USB stick or an SMB share, the ._ file can carry both the quarantine value and WhereFroms to the destination, even after the original is deleted from the Mac.
__MACOSX in Finder ZIPs
Archives made with Finder's "Compress" command include __MACOSX/._<name> entries holding the same data. Velociraptor ships MacOS.Forensics.AppleDoubleZip to read them at scale. Quarantine Parser reads quarantine and WhereFroms attributes from AppleDouble files directly: drop the ._ file or the __MACOSX folder with the rest of the evidence.
com.apple.provenance: present but opaque
On recent macOS, many files also carry com.apple.provenance, an 11-byte value. It is an opaque key into the ExecPolicy provenance_tracking table, not a URL or a timestamp. Quarantine Parser does not decode it. Note its presence, but do not draw conclusions from its bytes alone.
For a condensed reference to these artifacts, see the quarantine events cheat sheet on our sister site, and the investigation walkthrough for both patterns in context.
Frequently asked questions
Why does xattr -l show garbled text for kMDItemWhereFroms?
The value is a binary property list, not text. xattr -l prints it as if it were text, so the URLs appear mixed with unprintable bytes. Use xattr -l -x for an exact hex dump, or mdls -name kMDItemWhereFroms on a live system.
Does a file with kMDItemWhereFroms but no quarantine attribute prove tampering?
No. It is consistent with someone running xattr -d com.apple.quarantine, but a copy or transfer path that kept some extended attributes and not others could produce the same result. Treat it as a lead and test the specific tools and macOS version involved.
Which of the three records survives deletion of the file?
Typically only the QuarantineEventsV2 database row, since rows usually persist after the downloaded file is deleted. kMDItemWhereFroms and com.apple.quarantine are extended attributes and disappear with the file, unless an AppleDouble copy exists elsewhere.