One Bug, Five Vendors: Multi-Party Vulnerability Disclosure

When one bug hits five vendors, single-party VDP rules break. How multi-party coordinated disclosure works, and why your SLA says green while you're late.

Ernest Bursa

Ernest Bursa

Founder · · 16 min read
A security lead in his early fifties alone in an office kitchenette late at night, phone to his ear coordinating with another vendor, a closed laptop and cold coffee on the counter and a plain wall clock past midnight behind him

A vulnerability can hit several independent vendors at once, usually through a shared engine, library, or protocol. When that happens, it cannot run through an ordinary vulnerability disclosure program. Multi-party coordinated vulnerability disclosure requires a negotiated embargo date, an agreed CVE structure, and often a neutral coordinator, because no single vendor controls the timeline. Almost every VDP in production today is built for the opposite case: one company, one report, one clock.

Here is what happens when that assumption fails, which clock actually governs, and why your SLA dashboard can show green on the morning a shared flaw goes public.

One WebKit bug, every iOS proxy browser

On 4 August 2026, the researchers at Mysk published three WebKit behaviours that bypass a browser’s configured proxy and leak the device’s real IP address or DNS resolvers. The mechanisms are ordinary web platform features: <link rel="dns-prefetch"> hints, where “a page can embed unique per-visitor hostnames in these tags, then watch the queries arrive at its own authoritative DNS server from the visitor’s real network rather than the proxy’s”; WebAuthn Related Origin Requests, where the OS credential service fetches https://<rpId>/.well-known/webauthn off-proxy; and WebTransport, which opens HTTP/3 QUIC connections straight from the device.

The technical detail is not what makes this a landmark case. Platform policy is. As the write-up puts it: “Since Apple’s App Store policy requires every iOS browser to use WebKit, any iOS browser that relies on this API for proxying is affected, including all iOS Tor browsers and Psylo.”

One root cause in one proxy configuration API lands simultaneously on Apple’s own iCloud Private Relay and on every unrelated privacy browser shipping on iOS. Apple is the upstream engine vendor and a downstream product owner, so even the reflexive “escalate to upstream and move on” answer does not resolve who leads.

Note what the disclosure does not contain. No CVE. No shared embargo date. Outreach to two of the affected parties: “We’ve reached out to the Tor Project and the developers of Onion Browser on iOS about these issues.”

That is not a criticism of the researchers. It is a portrait of the default outcome when nobody runs the coordination. Every affected vendor learns at a different time, from a different source, and some learn from the blog post. That last position is an expensive place to be.

What is multi-party coordinated vulnerability disclosure?

Multi-party coordinated vulnerability disclosure (MPCVD) is the process for a vulnerability that affects several independent vendors at once, usually through a shared component, engine, or protocol. Unlike a single-vendor VDP, it requires a negotiated embargo date, an agreed CVE structure, and a coordinator, because no one party controls the timeline.

FIRST publishes the reference document, the Multi-Party Vulnerability Coordination and Disclosure guidelines (v1.1). It rests on four pillars (strong processes and relationships, clear communication, trust building, exposure minimisation) and defines five roles: Finder, Vendor, Coordinator, Defender, and Users/Deployers. Most VDPs only have vocabulary for the first two.

Why this is the normal case now, not the exotic one

Most of the vulnerabilities in a modern product live in code the vendor did not write and cannot unilaterally fix. Black Duck’s 2026 OSSRA report, based on “the analysis of 947 commercial codebases across 17 industries,” found:

  • 87% of audited codebases contained at least one vulnerability
  • 78% contained high-risk vulnerabilities, including 44% with critical-risk issues
  • The mean number of open source vulnerabilities per codebase “has more than doubled, rising 107% to an average of 581 vulnerabilities”
  • 93% contain components with no development activity in the last two years

The CERT Guide to Coordinated Vulnerability Disclosure names the cause without ceremony: “Many products today are not developed by a single organization. Instead, they are assembled from components sourced from other organizations.”

Run those numbers forward. If most of your attack surface is assembled rather than authored, then most of your vulnerabilities are structurally multi-party. The single-vendor report is the special case, and your tooling was built for it.

The four exits your triage queue offers, and why three are wrong

Open any VDP intake queue and look at the dismissal reasons. Kit’s Csirt module ships the conventional set: out_of_scope, duplicate, informational, not_reproducible, spam, other, and ai_slop. Every VDP has some version of this list, and for a shared-dependency report the two most tempting exits are both wrong.

out_of_scope is correct for “that is not our asset.” It is wrong for “that is our product, via someone else’s code.” Your users are exposed either way, and closing the report deletes your obligation without touching the exposure. It also reads as hostile: FIRST’s trust pillar warns that legal escalation creates “a chilling effect on desired security research,” and silently closing a shared-dependency report sits on the same spectrum. More on that dynamic in safe harbor and legal threats.

duplicate is semantically backwards. Today it means “the same bug, already reported to us,” and it closes the report. A shared-dependency case makes the opposite claim: the same root cause, in someone else’s product. That has to keep the report open, with a second owner and a second timeline.

informational buries it. And not_reproducible is the one that catches you out, because a downstream vendor often genuinely cannot reproduce an upstream flaw in isolation.

The exit that does not exist in any mainstream intake taxonomy is the fifth one: linked. Same root cause, different vendor, coordinated timeline, still ours to answer for. This matters more as AI-assisted research pushes more dependency-level findings into intake queues, a shift covered in AI and the economics of VDP triage.

Who sets the embargo date? Nobody, so learn the ceilings

There is no authority that sets embargo dates. FIRST is deliberately non-prescriptive: “In the absence of clear evidence of prior public disclosure (including active exploitation), stakeholders should provide a reasonable embargo period to vendors to investigate and develop fixes.” Where multiple coordinators are involved, “one coordinator should be selected as lead.”

So the date is negotiated. What makes the negotiation tractable is knowing the hard ceilings that other participants are already bound by.

Clock Length Binds
distros mailing list 14 days maximum, under 7 preferred, 1 day minimum Anyone who has notified Linux distributions
CERT/CC 45 days from report, “regardless of the existence or availability of patches or workarounds” Anyone who reported via CERT/CC
Google Project Zero 90 days, details 30 days post-patch; 7 days if exploited in the wild Any vendor Project Zero reports to
HackerOne default 30 days absent objection; 180-day finder backstop Programs running on HackerOne
OpenSSL pre-notification 2 weeks to OS distributors and derived projects; 1 week public announce Downstream consumers of OpenSSL

One rule falls out of that table, and it is the operative rule of multi-party disclosure:

The governing embargo is the shortest clock any participant is already bound by. If anyone in the case has gone to distros, you have at most 14 days, no matter what your own policy says. Your 90-day preference is irrelevant the moment someone else’s 14-day ceiling is running.

The CERT Guide explains why the ceilings exist at all: “The more parties involved in a case, and the longer the embargo period lasts, the more likely a leak becomes.” Longer embargoes are not safer. They are just longer.

One CVE or five? The identifier decision nobody explains

Both conventions exist, the choice is made per case, and it is a coordination decision rather than a clerical one. This is the least documented part of multi-party disclosure, and getting it wrong creates work for everyone downstream of you.

One CVE per protocol flaw, many vendors on it. KRACK’s authors stated the logic plainly: “Each CVE identifier represents a specific instantiation of a key reinstallation attack. This means each CVE ID describes a specific protocol vulnerability, and therefore many vendors are affected by each individual CVE ID.” Ten CVEs described the flaw, not the products.

One CVE per affected product, and the duplicate mess that follows. In the libwebp case, a second identifier was minted for the library after one already existed for the downstream browser bug. CVE-2023-5129 is now formally dead: “This CVE ID has been rejected or withdrawn by its CVE Numbering Authority. Duplicate of CVE-2023-4863.” Nothing about the vulnerability changed. The identifier changed, and every advisory, scanner rule, SBOM entry, and ticket reference keyed to it had to be re-pointed.

Mixed, when the protocol and the implementations are both wrong. Terrapin shipped CVE-2023-48795 for the general protocol flaw alongside CVE-2023-46445 and CVE-2023-46446 for AsyncSSH-specific attacks, plus CVE-2024-41909 for Apache MINA SSHD.

When nobody obviously owns assignment, CERT/CC’s policy is to assign the CVE itself in multi-vendor cases where authority is unclear. Coordination takes priority over waiting on CNA resolution.

The consequence for a downstream vendor is small and specific: your ledger must hold a reference to an upstream identifier that can later be superseded, not a hardcoded string pasted into a description field.

How to find the other four vendors

Three mechanisms, in ascending order of effort.

  1. security.txt (RFC 9116). A plain-text file at https://example.com/.well-known/security.txt with required Contact and Expires fields, plus optional Acknowledgments, Canonical, Encryption, Hiring, Policy, and Preferred-Languages. Published as an Informational RFC in April 2022, it exists so a finder can locate your reporting channel without guessing. It is also the cheapest way to make yourself findable by an upstream coordinator, which is the direction people forget. Setting up a VDP covers the rest of that groundwork.
  2. A coordinator. CERT/CC runs VINCE (Vulnerability Information and Coordination Environment), operated by CMU’s Software Engineering Institute and sponsored by CISA, where vendors register contacts and coordinate cases. This is the sanctioned answer to “I do not know who else ships this.”
  3. Manual, batched outreach. Which is what usually happens. Terrapin’s authors contacted roughly 29 SSH implementations across two rounds and notified CERT-Bund.

Set your expectations with a real number. CERT’s KRACK note, VU#228519, carries a vendor table whose footer reads “View all 183 vendors,” split across Affected, Not Affected, and a large Unknown block from whom no statement was ever received. In a genuine multi-party case, a substantial share of affected vendors never respond at all.

Terrapin: what a well-run multi-party disclosure looks like

Same shape as the WebKit case, opposite execution. A protocol flaw hitting around 29 independent SSH implementations, coordinated deliberately:

  • 2023-10-17 initial contact with OpenSSH and the AsyncSSH author
  • 2023-11-17 first vendor round, 17 implementations, plus CERT-Bund
  • 2023-11-21 second round, 12 more
  • 2023-12-11 notification to distros
  • 2023-12-18 public disclosure

62 days, four CVEs, one date. Notice the last two entries: distros was entered exactly 7 days before publication, inside that list’s preferred window rather than against its 14-day ceiling. That is what it looks like when someone is doing the arithmetic on purpose.

The range of real multi-party embargoes is wide. Cloudflare, Google, and AWS ran HTTP/2 Rapid Reset in roughly 46 days under active exploitation, from detection on 25 August 2023 to Google’s disclosure post on 10 October 2023. KRACK ran about 94 days. Meltdown and Spectre ran 216: Project Zero reported to Intel, AMD, and ARM on 2017-06-01 and published on 3 January 2018.

Forty-six to 216 days. No SLA covers that spread, which is the point. In a multi-party case, the date is an input, not a policy output.

The clock problem: why your SLA says green while you’re late

Here is the failure mode nobody has written down, and it is arithmetic rather than negligence.

Single-party SLA clocks are anchored to the moment the report reached you. Kit’s Csirt::Report::SlaTrackable computes every deadline from submitted_at, which is the correct and conventional design. Kit’s defaults are equally conventional: 72 hours to acknowledge, then resolution targets of 24 hours for super critical, 72 for critical, 168 for high, 336 for medium, and 720 for low or informational.

Now put those defaults next to the embargo ceilings.

336 hours is exactly 14 days, the distros list’s maximum acceptable embargo. 720 hours is 30 days, more than double any embargo the Linux distributions will honour.

A shared-dependency bug triaged as medium or lower will, by default, still be comfortably inside its own SLA on the morning the embargo expires and the flaw goes public. The dashboard reads green. The report is on track. And the fix is not shipped, the advisory is not drafted, and your users find out from someone else’s blog post.

Two things are broken at once. The anchor is wrong, because the governing clock started earlier, when a finder reported to a different vendor. And the terminal date is wrong, because it was set by negotiation among parties you may not have met.

This is a different failure from the SLA fairness problems that come up in bilateral programs. Those are disputes about whether the clock was honoured. This is a clock honoured perfectly that still ends up late.

What your ledger actually needs: a linked-disclosure record

The fix is one record, and most VDP tooling already has every primitive it needs to build it.

A linked disclosure is a first-class connection between a report in your ledger and an external disclosure elsewhere. It carries:

  • A role. upstream, downstream, or peer. This is the field that turns “unclassifiable report” into “case with a defined position in it.”
  • An external reference. The upstream CVE or advisory URL, and a coordinator case reference such as a CERT/CC VU number or a distros thread.
  • Two dates, not one. upstream_reported_at, the real start of the clock, and embargo_at, the agreed public date.
  • One rule. Whichever expires first governs. That single line is the whole fix.

Everything else is reuse. Kit’s SLA tiers already speak the right vocabulary (breached, at_risk, on_track, no_sla); they need a second predicate to evaluate against, so a report reads “acknowledgment: on track, embargo: 3 days” instead of a lone green tick.

Csirt::TrackerIssue already maintains managed, status-synced links to external systems, which is exactly what an upstream advisory needs when that advisory can be rejected later, as CVE-2023-5129 was. And Csirt::Report::Shareable already mints redacted, expiring, email-gated external shares.

Its own source comment gives the game away: “dismissing (‘out of scope, it’s the upstream vendor’s bug’) is exactly when a team forwards the redacted copy to that vendor.” The peer-vendor channel is already built. It is simply not modelled as coordination, so the recipient list stays an untracked forward rather than part of the case record.

The AI triage step is where this should land. When a first-pass tool flags “this looks like a dependency bug, not our bug,” the right outcome is a route, not a close.

That extends the argument in the silent patch problem: disclosure is a tracked stage, not a terminal state. The multi-party case adds one thing. That stage sometimes has four other participants, and your ledger has to know their names.

The regulator does not wait for the embargo

Under the EU Cyber Resilience Act, from 11 September 2026 manufacturers must report actively exploited vulnerabilities through ENISA’s Single Reporting Platform: an early warning within 24 hours, full notification within 72 hours, and a final report within 14 days of a corrective measure.

That clock is keyed to your awareness, not to the multi-party embargo. Learn on day 3 of a 90-day industry embargo that the shared flaw is being exploited, and your 24-hour obligation starts immediately.

Nothing in an embargo agreement excuses it, and no other participant can waive it on your behalf. Kit’s EU Cyber Resilience Act guide covers the obligation in full; the job here is just to name the collision. A coordination record that holds both dates is also the artefact that proves you met the regulator’s clock while the industry embargo was still running.

The runbook for a report that is not only yours

When a report says the flaw is shared, work this list before you touch a dismissal reason.

  1. Do not close it. Not out_of_scope, not duplicate. Mark it as linked and keep it open.
  2. Ask the finder three questions. Who else have you told, when did you tell them, and has this gone to any mailing list or coordinator?
  3. Find the shortest clock already running. If any answer above is distros, your ceiling is 14 days. If it is CERT/CC, 45. Write the date down.
  4. Decide whether you lead or follow. If the upstream vendor is coordinating, you are downstream and you follow their date. If nobody is, escalate to a coordinator rather than inventing one yourself.
  5. Get the identifier structure agreed early. One CVE for the flaw, or one per product? Ask before advisories are drafted, not after.
  6. Publish a security.txt. So the next upstream coordinator can find you without a LinkedIn search.
  7. Record both dates on the report. Ingest date for your SLA, embargo date for reality. Display both.
  8. Assume the CRA clock is independent. If exploitation is confirmed, the 24-hour obligation runs regardless of the embargo.
  9. Keep the peer share tracked. If you forward a redacted copy to another vendor, that recipient is part of the case, not a footnote in someone’s sent folder.
  10. Expect silence. A large share of contacted vendors never respond. The CERT Guide’s advice is to assume good faith and keep trying to re-establish contact. Being the vendor that goes quiet is how you end up named in someone else’s disclosure post.

None of this requires a PSIRT of twelve people. It requires a ledger that can express one sentence your current tooling probably cannot: this report is one of five. Add the link, add the embargo clock, apply the shortest-clock rule, and the report stops being a bug you cannot classify and becomes a case you can run.

Related articles

Ready to hire smarter?

Start free for 30 days. Cancel before it ends and you pay nothing. Set up your first hiring pipeline in minutes.

Start hiring free