Back to glossary

Full Disclosure

Full disclosure is publishing a vulnerability's complete details, often with exploit code, without first giving the vendor a private window to fix it.

Also known as Immediate disclosure, Uncoordinated disclosure

Full disclosure, also called immediate or uncoordinated disclosure, is publishing a vulnerability's complete technical details, often with a working exploit, without first giving the vendor or maintainer a private window to fix it. Defenders and attackers learn about the flaw at the same moment. Its credible threat is what keeps coordinated disclosure honest.

In open source, the line between full disclosure and coordinated disclosure is thinner than the debate assumes. A security fix merged into a public repository is already a disclosure, whether or not anyone has written an advisory. For a malicious package, there is no vendor to coordinate with at all. Our position: use coordinated disclosure with a short, fixed deadline for ordinary bugs. Disclose malware, backdoors, and flaws that are already being exploited immediately, because secrecy at that point protects only the attacker. And treat the public fix, not the CVE, as day zero.

What does full disclosure mean in cybersecurity?

#

Full disclosure in cybersecurity means the vendor, its users, and attackers all receive a vulnerability's details at once. Outside security, "full disclosure" just means revealing every relevant fact. Inside it, the phrase names one of three policies a finder can follow, and they differ in one variable: who learns first, and for how long.

  • Full disclosure. Publish everything immediately: affected versions, root cause, and often a working exploit. Historically that meant a post to a public mailing list. Today it is just as often a conference talk. At DEF CON 33 in August 2025, Marek Tóth presented password manager clickjacking bugs that several vendors had not yet fixed.
  • Coordinated disclosure. Report privately, give the vendor time to ship a fix, then publish. Many people still call this responsible disclosure.
  • Non-disclosure. Keep the bug, use it, or sell it. Exploit brokers and offensive teams hold zero-day vulnerabilities this way.

Figure 1 compares four timelines. Under full disclosure, details are public from day 0, and the vendor learns at the same moment as attackers. Under coordinated disclosure on Project Zero's 90+30 terms, the reporter and vendor hold the secret privately, and details publish 30 days after a fix ships or at day 90 if no fix ships. In open source practice, the private phase ends when the fix merges into a public repository and lands on a registry; a period follows in which the fix is public but no advisory explains it, and only then does the advisory publish. For a malicious package, only the attacker knows until researchers find it, there is no private vendor phase, and disclosure ends a window in which victims were installing the package.

Why full disclosure exists

#

Full disclosure exists because private vulnerability reports used to go nowhere. Bruce Schneier's 2007 essay describes the old pattern: researchers reported quietly, vendors sat on the reports, and when pressed, "Software companies would then call the vulnerabilities 'theoretical' and deny that they actually existed." Public mailing lists broke that equilibrium. The Full-Disclosure list, created by John Cartwright and Len Rose in July 2002, carried unvetted vulnerability drops for almost 12 years. Cartwright shut it down in March 2014, and Gordon "Fyodor" Lyon relaunched it on March 25, 2014.

Coordinated disclosure won the mainstream, but only by absorbing full disclosure as its enforcement mechanism. Schneier stated the dependency plainly in the same essay: "And it remains a good idea only as long as full disclosure is the threat." Every major disclosure policy today is a full disclosure deadline with a grace period attached.

PolicyPrivate windowWhat happens at the deadline
CERT/CC45 days from the initial reportPublished, whether or not a fix exists
Google Project Zero90 days, or until 30 days after a fix that ships soonerThe full bug report becomes public
Project Zero, exploited in the wild7 daysThe full bug report becomes public
linux-distros list14 days maximum, under 7 preferredThe reporter must post details to oss-security
Linux kernel security teamFix release delayed up to 7 calendar days, 14 by exceptionThe fix is released publicly

Sources: CERT/CC policy, Project Zero FAQ, linux-distros list policy, Linux kernel security-bugs.

These deadlines are not bluffs. On April 3, 2025, CERT/CC published VU#252619, a set of insecure deserialization flaws in every PyTorch Lightning release through 2.4.0, with no patch available, because the vendor "has not responded to disclosure communications." We covered the PyTorch Lightning deserialization vulnerabilities at the time. A coordinated process ended in full disclosure, exactly as designed.

Google Project Zero pushed the model further on July 29, 2025 with its Reporting Transparency trial. Under the trial, about a week after filing a report, Project Zero publicly lists the vendor, the product, the report date, and the deadline, with no technical details. Its stated target is the "upstream patch gap," the delay before downstream products pick up a fix that already exists upstream.

How does full disclosure happen in open source without an announcement?

#

In open source, full disclosure happens whenever a security fix merges into a public repository, because the diff reveals the vulnerability to anyone who reads it. The linux-distros list writes this into its policy: if "the fix is already in a publicly accessible repository, we generally consider the issue public." Most projects do not behave as if that sentence were true.

The Next.js middleware bypass, CVE-2025-29927, shows the mechanism. Researchers Allam Rachid and Allam Yasser reported it privately through GitHub on February 27, 2025, which is coordinated disclosure by any definition. Next.js used an internal header, x-middleware-subrequest, to stop middleware from recursing, and it trusted that header from clients. A request carrying the right value skipped middleware entirely, including authentication checks.

On March 17, 2025 at 20:56 UTC, the fix merged publicly as PR #77201. Its title was "Update middleware request header." Its description read: "This just adds an additional header to our internal filtering list for middleware." The test it added contained the exploit:

TypeScript
it('should filter request header properly', async () => {
  const res = await next.fetch('/redirect-to-somewhere', {
    headers: {
      'x-middleware-subrequest':
        'middleware:middleware:middleware:middleware:middleware',
    },
    redirect: 'manual',
  })

  expect(res.status).toBe(307)
  expect(res.headers.get('location')).toContain('/somewhere')
})

Keeping the GitHub repository private would not have closed the gap. The registry is a second disclosure channel, because every published version is a public tarball. Anyone can diff two releases with a stock npm command:

Shell Session
$ npm diff --diff=next@15.2.2 --diff=next@15.2.3 dist/server/lib/server-ipc/utils.js
@@ -74,6 +74,12 @@
         if (INTERNAL_HEADERS.includes(header)) {
             delete headers[header];
         }
+        // If this request didn't origin from this session we filter
+        // out the "x-middleware-subrequest" header so we don't skip
+        // middleware incorrectly
+        if (header === 'x-middleware-subrequest' && headers['x-middleware-subrequest-id'] !== globalThis[Symbol.for('@next/middleware-subrequest-id')]) {
+            delete headers['x-middleware-subrequest'];
+        }

The registry also timestamps exactly when each patched build became public:

Shell Session
$ npm view next time --json | jq '{"14.2.25": .["14.2.25"], "15.2.3": .["15.2.3"], "13.5.9": .["13.5.9"], "12.3.5": .["12.3.5"]}'
{
  "14.2.25": "2025-03-17T22:10:43.269Z",
  "15.2.3": "2025-03-18T00:18:54.395Z",
  "13.5.9": "2025-03-22T20:21:27.732Z",
  "12.3.5": "2025-03-23T06:41:24.140Z"
}

According to Vercel's postmortem, the CVE became public on March 21 at 10:17 UTC.

Figure 2 shows the CVE-2025-29927 timeline in UTC. The private report arrived on February 27, 2025 at 06:03. PR #77201 merged publicly on March 17 at 20:56, with a test that sends the exploit header. next@14.2.25 reached npm at 22:10 that day, and next@15.2.3 followed at 00:18 on March 18. GitHub issued the CVE ID at 18:03 on March 18, but it was not yet public. The CVE became public on March 21 at 10:17, about 85 hours after the fix merged. The older lines were patched later: next@13.5.9 on March 22 at 20:21, 34 hours after the CVE, and next@12.3.5 on March 23 at 06:41, 44 hours after it. For those two lines, the vulnerability was public with no patch available.

CVE-2025-29927 is not a story about one careless team. Any project that ships through a public repository and a public registry runs a full disclosure the moment it releases a fix. The only choice is how long the gap lasts before users are told what the diff means. A project can shorten it by developing the fix in a private fork and publishing the release and the security advisory together. It cannot get the gap to zero, because users need hours or days to upgrade and attackers need only the diff. In July 2026, Next.js moved to scheduled security releases announced in advance, so hosting providers can deploy mitigations such as firewall rules before the patched code is public.

Why coordinated disclosure breaks down for malicious packages

#

Coordinated disclosure assumes a vendor who wants the flaw fixed. A malicious package inverts that assumption: the publisher is the attacker, and every hour of private coordination is another hour of installs. The xz backdoor made this concrete for a trusted upstream project. When Andres Freund found it, he reported privately to Debian and the distros list, then published on oss-security on March 29, 2024. He explained why one channel was skipped: "Given the apparent upstream involvement I have not reported an upstream bug."

Malware also falls outside the machinery that coordinated disclosure feeds. Most malicious packages never receive a CVE, because nothing is "vulnerable" in the usual sense. The package is working as its author intended. The xz backdoor became CVE-2024-3094 only because it shipped inside a widely distributed upstream project. Disclosure for malware means publishing package names, versions, and indicators of compromise, and asking the registry to remove the package.

Our threat research team discloses that way, usually while the packages are still live. When we published the 10 npm typosquatted packages that deploy a credential harvester in October 2025, they had been on npm for over four months and had more than 9,900 downloads; we had petitioned npm for their removal. The SANDWORM_MODE worm shows the one kind of coordination that still makes sense for malware. We notified npm, GitHub, and Cloudflare before publishing so they could dismantle the campaign's infrastructure, not so anyone could prepare a patch. npm then removed the packages, and GitHub removed the attacker's infrastructure.

The trade-off is real. Publishing indicators while a campaign runs tells the operator to rotate infrastructure and rename packages. We accept that cost, because the alternative leaves developers installing known malware while we wait for a takedown we do not control.

Why embargoes are failing in 2026

#

Coordinated disclosure depends on a secret staying secret. In 2025 and 2026, three pressures have made that harder: maintainer capacity, cheap rediscovery, and leaky coordination groups.

The first pressure is capacity. On May 27, 2025, libxml2's lone volunteer maintainer at the time, Nick Wellnhofer, rewrote the project's README. The libxml2 policy change ended embargoed reports. The README's history is in the repository, so you can see the policy flip twice:

Diff
# git log -p -- README.md in GNOME/libxml2, Security section only

# 35d04a0, 2025-05-27, Nick Wellnhofer: "README: Set expectations straight"
+As such, we treat security issues like any other bug. Each security report
+we receive will be made public immediately and won't be prioritized.

# 9c80a89, 2025-12-06, Nick Wellnhofer steps down as maintainer
+This project is unmaintained and has
+[known security issues](https://gitlab.gnome.org/GNOME/libxml2/-/issues/346).

# 0704f52, 2025-12-10, new maintainers: "Write a more possitive Security section"
+To **report security bugs**, you can create a confidential issue with
+the "security" label. We will review and work on it as a best effort.

As of November 2026, libxml2 again accepts confidential reports. The roughly six months of full disclosure by default remain the clearest case of a maintainer choosing it on purpose, and the reason was workload, not ideology.

The second pressure is rediscovery. When a widely available AI tool can find a bug on demand, the person who reported it may not be the only one who knows. The Node.js public workflow proposal, opened in February 2026 by security maintainer Rafael Gonzaga, argues exactly this about lower-severity reports. "These findings are effectively public already," he wrote. Node.js received 65 HackerOne reports in a single recent month, against 252 over the previous two years. As of its July 2026 Security Working Group meeting, Node.js had not changed its policy.

The third pressure is the size of the group that has to keep the secret. The PHP embargo dispute of October 2026 shows the failure modes stacking up. CVE identifiers for two critical remote code execution bugs leaked on October 20 at about 15:00 UTC. PHP pulled the release forward by a day. At about 20:00 UTC, a research firm accidentally published a video of its exploits. On October 21 at 07:41 UTC, more than six hours before the coordinated 14:00 UTC release, a container image vendor shipped patched builds, citing exploitation in the wild. The PHP Foundation said its security team had found no functional public exploit by release time. Every distributor that received the patch early was one more place the secret could leak.

The pattern is consistent. Embargoes still work for a small, vetted group and a short window. They do not survive a large distribution list, a 90-day clock, and a bug that a language model can find again next week.

When is full disclosure the right call?

#

Full disclosure is the right call when keeping the secret no longer protects users. That covers malware, backdoors, bugs already exploited in the wild, and vendors that refuse to engage. For everything else, coordinated disclosure with a short deadline gives users a fix before attackers get a map.

ApproachWho learns firstPublic whenBest fitBreaks when
Full disclosureEveryone at onceImmediatelyMalware, backdoors, bugs exploited in the wild, unresponsive vendorsAttackers did not know, and users cannot mitigate without a fix
Coordinated, short deadline (7 to 14 days)Maintainer and a small vetted groupWithin two weeksMost open source bugs with an active maintainerThe fix needs more time than the window allows
Coordinated, long deadline (90 days)Vendor, then downstream partnersAfter the fix, or at the deadlineFixes that must ship across many downstream vendors at onceThe fix lands in a public repo or registry early, or someone rediscovers the bug
Non-disclosureFinder onlyNever, unless exploitedNo defensive useAlways, for the people running the software

Verdict: coordinated disclosure with a hard deadline is the right default for an ordinary vulnerability with a responsive maintainer. Use the shortest window the fix allows, closer to the 7 to 14 days of the Linux lists than to 90. Go straight to full disclosure for malware, backdoors, and exploited bugs. Fall back to full disclosure when a vendor stops responding, as CERT/CC did with PyTorch Lightning. Do not confuse "unpatched" with "secret": once the fix is in a public repository or registry, the bug is public.

What full disclosure means for teams consuming open source

#

For a team consuming open source, full disclosure means the clock starts when a fix or report becomes public, not when an advisory reaches a scanner. The advisory pipeline has fallen further behind that moment. In April 2026, NIST stopped enriching most CVEs, after CVE submissions grew 263% between 2020 and 2025. A scanner that waits for enriched NVD data can learn about a fix days or weeks after attackers could have read the diff. It will miss most malware entirely, because most malware never gets a CVE.

That leaves three controls, each with a cost. Watching upstream releases and security-labeled commits catches silent fixes early, but most commits that look like security fixes are not, so the signal is noisy. Reachability analysis tells you whether a newly public bug touches code you actually call, so you can patch the ones that matter first. It depends on accurate call graphs and says nothing about malware. Analyzing package contents before install catches malicious code without waiting for any disclosure. Socket's Known malware alert fires when our AI scanner flags a package and a researcher confirms it, or when its files match previously confirmed malware. It cannot tell you about a memory corruption bug that nobody has found yet.

Disclosure policy has always been a negotiation over who gets a head start. Automated discovery is now producing bugs faster than maintainers can fix them and faster than embargoes can contain them. The open question is no longer whether full disclosure is ethical. It is whether a secret can last long enough, in a public repository and a public registry, for coordinated disclosure to buy users anything at all.