Methodology v1.0.0
This site measures how long Apple users stay exposed to a security flaw after a fix for it already exists somewhere. It does not rebuild a CVE database: it combines Apple's advisories, CISA's exploited-vulnerability catalog and NVD into three timing metrics.
Sources
- Apple security releases (and yearly archives): every release, its date, and its advisory. Release dates are Apple's, as US calendar dates; we treat them as UTC dates.
- Apple advisories (“About the security content of …”): which CVEs each release fixes, “Entry added” dates, and the note “Apple is aware of a report that this issue may have been exploited”.
- CISA Known Exploited Vulnerabilities (KEV): date added, joined by CVE ID (some Apple-shipped CVEs are filed under other vendors, e.g. Google).
- NVD CVE API 2.0: the record's published date (UTC).
Ingestion runs every 6 hours. Each run re-reads Apple's index, every advisory released in the last 90 days (Apple adds CVEs to existing advisories weeks or months later), the full KEV catalog, and every NVD record modified since the previous run, with a full NVD resync weekly. Older advisories are re-read daily up to 400 days, then monthly. The dataset is a single file in the project's git repository; every change to it is a commit, and the site is rebuilt only when it changes. Ingestion caches every response and refuses to publish if the dataset would shrink by more than 10% (a sign that a source changed format). SOFA (sofa.macadmins.io) was evaluated and not used: it lacks iOS 15–17 and iPadOS 17, and some older macOS release dates in it are wrong.
Definitions
- Branch
- A major OS version line that receives its own updates, e.g. iOS 16 or macOS 14 Sonoma. iOS and iPadOS are counted separately.
- First fix
- The release date of the earliest Apple update (including Rapid Security Responses and Background Security Improvements) whose advisory lists the CVE.
- Exploited
- Listed in the CISA Known Exploited Vulnerabilities (KEV) catalog, or Apple's advisory says the issue “may have been exploited”.
- KEV date added (proxy)
- CISA KEV “date added” is when CISA catalogued evidence of exploitation. It is a lagging proxy: exploitation started on or before that date, usually well before.
- Backport gap
- For one CVE and one branch: the branch's first fix date minus the earliest fix date across all branches of the same platform.
- No fix listed
- The branch is still maintained (it shipped a security update after the earliest fix, or its last security update is under 180 days old), but no Apple advisory lists this CVE for it as of the data date. The branch may be unaffected; Apple does not publish “not affected” statements.
- Branch ended
- The branch shipped no security update after the earliest fix and none in the 180 days before the data date, so it is treated as ended and not counted as missing a backport. Updates without published CVE entries do not keep a branch alive.
- Fixed at branch release
- The branch was first released after the earliest fix, so it is not a backport and is not counted. “Listed”: its advisory names the CVE. “Inherited”: it does not, and the fix is assumed to be in the branch from its first release.
- Third-party component
- CISA KEV files the CVE under a vendor other than Apple (e.g. Google for Chromium code shipped in WebKit/ANGLE). The flaw is in a component Apple ships but does not own.
- Disclosure lag
- NVD publication date minus the earliest fix date. Negative when the CVE record was published before the fix.
The three metrics
1. Exploited before patch
Headline: how many exploited CVEs Apple itself described as “may have been exploited” when it released the fix, i.e. attacked before a patch existed. How long before is not public. Secondary: for each exploited CVE in KEV, first fix date minus KEV date added. Positive means CISA had catalogued exploitation before any Apple patch existed. For Apple this is rare; KEV usually follows the patch by days, and sometimes by years when exploitation is discovered later. The number is therefore a lagging proxy, not the start of exploitation, which is not public. Apple's own “may have been exploited” note is shown alongside: it means exploitation began before the patch, for an unknown length of time.
2. Backport gap
Per CVE and platform (iOS, iPadOS, macOS separately): find the earliest fix on any branch. Each branch that existed on that date is then classified as fixed (gap = its first fix minus the earliest fix), no fix listed, or branch ended. A branch first released after the earliest fix is shown as fixed at branch release and is not counted. The headline reports one branch, never a mix: the oldest branch still maintained on the data date (last security release under 180 days old), with its median and worst gap, over exploited CVEs only, where a missing backport is least likely to mean “not affected”.
3. Disclosure lag
NVD published date minus the first fix date, over all CVEs in the window.
Every metric reports the median (the mean of the two middle values for even counts) and the worst case, with the CVE that produced it. Means are not shown. Only CVEs whose earliest fix is on or after 2023-01-01 are counted; releases since 2022 are ingested so that a 2022 first fix is not mistaken for a 2023 one.
Edge-case rules
- A CVE listed by several releases of the same branch: the earliest of them is the branch's fix date.
- Rapid Security Responses and Background Security Improvements (letter-suffix updates such as 16.5.1 (a)) count as fixes on their date, including (a) releases that Apple later replaced with (c).
- A release Apple listed twice (re-release): the first date counts; later dates are shown.
- A CVE added to an advisory after the release (“Entry added”): the fix date stays the release date; the late entry is shown on the CVE page and counted under disclosure lag.
- Missing NVD or KEV dates are shown as “unknown” and left out of medians, never estimated.
- A branch with no security release after the earliest fix is “branch ended”, not “no fix listed”, unless its last security release is under 180 days old: then its next one may simply not be due yet, and it stays “no fix listed” as of the data date. Updates without published CVE entries (e.g. iOS 12.5.8, January 2026, which Apple lists with no published CVE entries) do not keep a branch alive.
- A branch first released after the earliest fix (e.g. a new major version) is “fixed at branch release”: listed if its advisory names the CVE, otherwise assumed inherited. It is never counted as a backport gap or as missing a fix.
- CVEs that CISA KEV files under a vendor other than Apple are labelled “third-party component”; they stay in all metrics, because Apple users are exposed until Apple ships the fix.
- An older branch fixed before the newest one: the older branch sets the earliest fix date and the newest branch gets the gap.
Known limitations
- “No fix listed” cannot be told apart from “not affected”: Apple does not publish which branches are unaffected.
- Some branches serve two groups: devices that cannot upgrade, and users who chose not to. The numbers describe the branch, not the device.
- Apple advisories are HTML pages; a format change can break parsing. The shrink guard stops publication rather than publishing gaps.
- Release dates are calendar days. Two releases on the same day have a gap of 0 days even if they shipped hours apart, and time zones are ignored.
- watchOS, tvOS, visionOS and Safari are out of scope.
Version history
| Version | Date | Change |
|---|---|---|
| 1.0.0 | First published methodology. |
Data corrections
No corrections so far. Any change to a published number caused by a source error, parser fix or rule change is listed here.