1,413 Fixes in One Month: Triage Microsoft's October 2026 Patch Tuesday by Risk Cohort
Microsoft's October 2026 Patch Tuesday resolved 1,413 CVEs: 1,102 in Windows, 134 in Office, 61 in developer tools and 36 in SharePoint Server, with Exchange Server, Azure and Defender also receiving fixes. That single month exceeds everything the company patched in all of 2025, and it pushes the 2026 total past 4,000. One of those 1,413 is being exploited right now. The more interesting part of the release is a new way of organising the queue, which is worth adopting even if you never open the release notes again.
The exploited flaw defeats Mark of the Web, the control that tags downloaded files
The record, in numbers
Microsoft's October 2026 Patch Tuesday fixed 1,413 CVEs, according to the release, of which 1,102 affect Windows, 134 affect Office, 61 affect developer tools and 36 affect SharePoint Server. Exchange Server, Azure, Defender and other products were patched in the same release. Two comparisons set the scale. The month's total is larger than the number of vulnerabilities Microsoft patched in the whole of 2025, and it takes the 2026 year-to-date count past 4,000. A queue of that size is not a triage exercise anyone completes by reading. The question stops being which ones matter and becomes which order a fixed number of hours can actually clear.
# Exploited first, always. Intersect CISA KEV with what you actually run.
import json, urllib.request
KEV = "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json"
ASSETS = {"windows-server-2022": ["CVE-2026-96951"], "sharepoint-2019": ["CVE-2026-108398"]}
with urllib.request.urlopen(KEV, timeout=30) as resp:
kev = json.load(resp)
exploited = {v["cveID"]: v for v in kev["vulnerabilities"]}
print("KEV entries:", len(exploited))
for asset, cves in ASSETS.items():
for cve in cves:
entry = exploited.get(cve)
if entry:
print(asset, "|", cve, "| due:", entry.get("dueDate"),
"| known ransomware use:", entry.get("knownRansomwareCampaignUse"))
# CVE-2026-96951 landed in KEV on October 13, 2026; federal agencies were given
# until October 16. Your own SLA should have been tighter than that, not looser.The one being exploited: CVE-2026-96951
CVE-2026-96951 is a Windows shell security feature bypass rated 8.8 out of 10 that lets an attacker evade Mark of the Web. Mark of the Web is the tag Windows applies to files downloaded from the internet, and it is what tells Defender SmartScreen and Office Protected View to restrict automatic execution. Bypassing it means a malicious file can launch without the usual warnings. Microsoft describes the attack as sending a crafted file by email or instant message and convincing the user to act, which is the standard delivery path for this bug class. Fujitsu, Anthropic and an independent researcher reported it separately. CISA added it to the Known Exploited Vulnerabilities catalog on October 13 and gave federal agencies until October 16.
# Cohorts are a classification you own, not a vendor feed. Keep the rules in a file.
import json
from collections import Counter
RULES = [
("filesystems, storage and backup", ["ntfs", "refs", "storage", "backup", "vss"]),
("graphics, media and content processing", ["gdi", "directwrite", "codec", "image", "media"]),
("office document and mail clients", ["outlook", "word", "excel", "office", "onenote"]),
("core and kernel privilege boundaries", ["kernel", "win32k", "ntoskrnl", "privilege"]),
("installation, deployment and update services", ["msi", "clickonce", "update", "installer"]),
("remote-access and RDP deployments", ["rdp", "rdp client", "remote desktop", "gateway"]),
("authentication, credentials and cryptography", ["kerberos", "schannel", "lsass", "credential"]),
("networking and protocol stack", ["tcp", "dns", "dhcp", "tls", "smb", "http.sys"]),
]
def cohort(title, summary):
text = (title + " " + summary).lower()
hits = [name for name, words in RULES if any(w in text for w in words)]
return hits[0] if hits else "unclassified"
month = [
{"id": "CVE-2026-96951", "title": "Windows Shell Security Feature Bypass",
"summary": "attacker evades mark of the web protections"},
{"id": "CVE-2026-108398", "title": "Windows Defender Application Control Bypass",
"summary": "wdac enforcement bypass"},
{"id": "CVE-2026-92707", "title": "MessagePack-CSharp Denial of Service",
"summary": "developer tools and .net library"},
]
counts = Counter(cohort(c["title"], c["summary"]) for c in month)
for name, n in counts.most_common():
print(n, name)
# On the real release you feed 1,413 rows through this and get a work plan,
# not 1,413 individual decisions.What a 1,413-CVE month needs is capacity, not resolve
Why the queue exploded
The surge is largely attributed to AI-assisted discovery of vulnerabilities in the vendors' own code, which is the same capability that makes attackers faster and is now also making patch releases larger. Independent tracking of the monthly cadence is equally stark: ThreatDown reported that vendors addressed 998 CVEs around the September 2026 Patch Tuesday, against 96 in the same window a year earlier. Two entries in this release were public before a fix existed: CVE-2026-108398, which bypasses Windows Defender Application Control enforcement, and CVE-2026-92707, a denial-of-service flaw in the MessagePack-CSharp component used by Visual Studio and .NET. Pre-disclosure is the case where your own detection has to carry the load, because there was no patch to deploy.
# A cohort is only useful if you can answer its shared question from your inventory.
import json
CMDB = {
"fields": ["os_build", "installed_software", "internet_facing", "backup_agent",
"rdp_roles", "browser_used_by_staff", "delivery_mechanism"],
}
COHORT_QUESTIONS = {
"graphics, media and content processing":
"internet_facing",
"office document and mail clients":
"delivery_mechanism",
"remote-access and RDP deployments":
"rdp_roles",
"filesystems, storage and backup":
"backup_agent",
}
def coverage(cmdb, questions):
report = {}
for cohort, field in questions.items():
report[cohort] = "answerable" if field in cmdb["fields"] else "MISSING FIELD: " + field
return report
for k, v in coverage(CMDB, COHORT_QUESTIONS).items():
print(("OK " if v == "answerable" else "GAP ") + k + " -> " + v)
# The gap lines are the actual output of this exercise: they are the fields
# you cannot answer, which means those cohorts cannot be triaged at all.Risk cohorts: the useful part of the release
Microsoft introduced risk cohorts: groups of CVEs that require a similar customer assessment. A cohort is not a root cause and not a severity band. What the members share is a question about your environment. The illustrative examples come with counts: Windows filesystems, storage and backup at 136 CVEs, Office document and mail clients at 135, graphics, media and content processing at 131, core and kernel privilege boundaries at 109, installation and update services at 103, device and peripheral surfaces at 76, DNS and address infrastructure at 76, remote-access and RDP deployments at 65, authentication and cryptography at 61, networking and protocol stack at 53, virtualisation and container hosts at 45, file sharing at 39, endpoint management at 38 and web, RPC and messaging services at 27. Microsoft is careful to say these are exploratory, are not official categories and do not change update guidance.
# Mark of the Web is the control CVE-2026-96951 defeats. Verify it is still enforced.
# PowerShell, on a representative endpoint.
$zone = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap"
# 1. Zone 3 (Internet) files should be tagged and warned about on open.
Get-ItemProperty -Path $zone -Name "*" |
Where-Object { $_.PSObject.Properties.Name -notlike "PS*" } |
Select-Object -First 15
# 2. Confirm Attachment Manager policy is not silently relaxing the warning.
$am = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments"
if (Test-Path $am) { Get-ItemProperty $am } else { "no Attachment Manager policy set" }
# 3. Confirm the October cumulative update for this build is installed.
Get-HotFix | Where-Object { $_.InstalledOn -gt (Get-Date).AddDays(-14) } |
Select-Object HotFixID, InstalledOn | Format-Table -AutoSize
# A bypass is only exploitable if the file arrives already de-tagged.
# If MoTW is disabled by policy anywhere, that host belongs at the front of the wave.Group by the shared environment question, not by CVSS score
Running it in a day
The workflow that falls out of this is short. First, filter everything already in the Known Exploited Vulnerabilities catalog, because exploitation answers the priority question outright. Second, take the cohorts whose shared question you can answer from your own inventory, and answer it once: which assets process untrusted media, which run RDP roles, which back up unverified data. Third, feed the unanswerable cohorts back as inventory gaps, because a cohort you cannot answer is a cohort you also cannot deprioritise honestly. Fourth, schedule the update by cohort rather than by product, so a single maintenance window covers a set of machines that share a reason to be patched together. Loop the whole thing monthly and the release stops being an event.
# Finally: turn the queue into waves, constrained by the people who can test it.
import math
COHORTS = [
("exploited in the wild", 1, 4),
("remote-access and RDP deployments", 65, 8),
("office document and mail clients", 135, 12),
("graphics, media and content processing", 131, 10),
("core and kernel privilege boundaries", 109, 16),
("filesystems, storage and backup", 136, 16),
]
def plan(cohorts, testers=3, cves_per_tester_day=6, window_days=14, paused_services=2):
capacity = testers * cves_per_tester_day * window_days
capacity //= paused_services
total = sum(cves for _, cves, _ in cohorts)
waves, remaining = [], capacity
for name, cves, _risk in cohorts:
share = max(1, math.ceil(cves / total * capacity))
waves.append((name, cves, share, "fits" if share <= remaining else "overflow"))
remaining -= share
return waves, capacity
waves, capacity = plan(COHORTS)
print("testing capacity this window:", capacity, "CVE-reviews")
for row in waves:
print(row)
# 1,413 CVEs and 3 testers is a capacity problem, not a discipline problem.
# Publish the capacity number next to the cohort counts.What not to conclude from any of it
Risk cohorts are a starting point, not a decision, and Microsoft says so explicitly: each CVE still needs review for active exploitation, severity, attack vector, user interaction and product-specific guidance. The cohort grouping saves repeated environment analysis, it does not replace it. Two other misreadings are worth pre-empting. A large release does not mean the products are getting worse; it means discovery got cheaper, including for the vendor. And a low CVSS score is not a reason to ignore a finding that chains with something else you have not patched, which is exactly how separate low-severity bugs become one high-severity exploit path. Triage on reachable impact, and let the score be one input rather than the verdict.
📌 Frequently Asked Questions
How many vulnerabilities did Microsoft fix in October 2026?
1,413 CVEs: 1,102 in Windows, 134 in Office, 61 in developer tools and 36 in SharePoint Server, with Exchange Server, Azure, Defender and other products also patched. That is more than Microsoft patched in all of 2025, and it takes the 2026 total past 4,000.
Which CVE is being exploited in the wild?
CVE-2026-96951, a Windows shell security feature bypass with a CVSS score of 8.8 that allows an attacker to evade Mark of the Web. CISA added it to the Known Exploited Vulnerabilities catalog on October 13, 2026, with a federal remediation deadline of October 16.
What is a risk cohort?
A group of CVEs that require a similar customer assessment. The members may share neither root cause nor CVSS score; what they share is a question about your environment, such as which assets process untrusted media or which hosts run remote-access roles. Microsoft describes them as exploratory and says they do not change update guidance.
Why did the number of patches jump so much?
The surge is largely attributed to AI-assisted vulnerability discovery in vendors' own code. The month-over-month scale is visible elsewhere too: ThreatDown reported 998 CVEs around the September 2026 Patch Tuesday against 96 in the same window a year earlier.
Should I still read every CVE?
Yes. Microsoft's own guidance is that a cohort is a starting point and not a final decision, and that each CVE still needs review for active exploitation, severity, attack vector, user interaction and product-specific guidance. Cohorts reduce repeated environment analysis; they do not replace per-CVE assessment.
🔧 Recommended Tools
📚 Sources
- SecurityWeek: Microsoft patches record 1,413 vulnerabilities (Oct 14, 2026)
- Microsoft MSRC update guide: CVE-2026-96951
- CISA: adds two known exploited vulnerabilities to the catalog (Oct 13, 2026)
- Microsoft MSRC blog: using risk cohorts to prioritize security updates
- Microsoft: illustrative CVE list per risk cohort (PDF)
- Redmondmag: AI-driven vulnerability surge puts security teams under pressure (ThreatDown data)