From 1dc57ba2b1a1dfd8da58de64f2312e65095a6ac9 Mon Sep 17 00:00:00 2001 From: Ayla Croft Date: Wed, 7 Oct 2026 19:43:13 -0400 Subject: [PATCH] SECURITY: CVE IDs come from the EEF CNA, which covers hex.pm, not from GitHub The CVEs section said GitHub, a CNA for the repositories it hosts, assigns this package's CVEs from the advisory draft. GitHub does not assign for a package another CNA covers, and the Erlang Ecosystem Foundation's CNA covers every active package on hex.pm: the four requests made to GitHub for 0.10.1's advisories (2026-09-23) were never going to be answered. The section now gives the EEF CNA's maintainer process (its points of contact as collaborators on the draft, the ID entered as an existing CVE) and says what happened to 0.10.1's requests. The pin in security_policy_test.exs moves to the corrected sentence; it fails on the old text. Signed-off-by: Ayla Croft --- CHANGELOG.md | 8 ++++++++ SECURITY.md | 14 ++++++++++---- test/beam_mcp/security_policy_test.exs | 15 +++++++++------ 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f65387..1438d95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,14 @@ All notable changes to this project are documented here. The format follows ## [Unreleased] +### Changed: CVE IDs come from the EEF CNA (SECURITY.md) + +- `SECURITY.md` said GitHub assigns this package's CVEs. GitHub is a CNA but does not assign + for a package another CNA covers, and the Erlang Ecosystem Foundation's CNA covers every + active package on hex.pm, so the CVE requests made to GitHub for 0.10.1's advisories were + never answered. The section now follows the EEF CNA's maintainer process, and its pin + (`security_policy_test.exs`) holds the corrected sentence. + Follow-ups from the first human review of 0.10.1 (Sean MacGuire). No public entry moves. ### Changed: a schema that becomes unenforceable after startup is a server fault diff --git a/SECURITY.md b/SECURITY.md index 2d82a20..7a14b35 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -54,10 +54,16 @@ an injected function is out of scope at any level. ## CVEs -Advisories are published from this repository's GitHub Security Advisories. GitHub is a CVE -Numbering Authority (CNA) for repositories it hosts, so a CVE is requested from the advisory -draft and assigned before publication when the defect warrants one: Critical and High always -do; Medium when a consumer needs an identifier to act on; Low rarely. A published advisory +Advisories are published from this repository's GitHub Security Advisories. CVE IDs come from +the [Erlang Ecosystem Foundation's CNA](https://cna.erlef.org/), the CVE Numbering Authority for +every active package on hex.pm (GitHub is a CNA too, and does not assign for a package another CNA +covers). An advisory that warrants one gets one before publication: Critical and High always do; +Medium when a consumer needs an identifier to act on; Low rarely. The EEF CNA's points of contact +(@IngelaAndin, @maennchen, @voltone) are added to the draft advisory as collaborators, the CVE is +left as "request later", and the ID they assign is entered as an existing CVE +([their maintainer process](https://cna.erlef.org/maintainer-process)). The four advisories of +`0.10.1` were first requested from GitHub, which cannot assign them, and were then requested from +the EEF CNA. A published advisory reaches the GitHub Advisory Database and OSV, the source hex.pm's registry advisories are fed from and `mix hex.audit` reads, so a consumer running the audit sees it against their lock file without this project telling them. diff --git a/test/beam_mcp/security_policy_test.exs b/test/beam_mcp/security_policy_test.exs index 098a20f..b085ce4 100644 --- a/test/beam_mcp/security_policy_test.exs +++ b/test/beam_mcp/security_policy_test.exs @@ -100,13 +100,16 @@ defmodule BeamMCP.SecurityPolicyTest do assert critical_window =~ "patch release of the supported minor carrying only the fix" end - test "the CVE path names GitHub as the CNA and the advisory as where it starts" do - # The sentence, not the abbreviation: a regex on "GitHub ... CNA" passed a negation and - # failed a true sentence without the parenthetical (a lane's two plants). - # Through the consequence, so a negation appended after the clause fails too; \s+ between - # words, so a reflow of the paragraph does not (G-074). + test "the CVE path names the EEF CNA, which covers hex.pm, and the advisory as where it starts" do + # The sentence, not the abbreviation, through its consequence, with \s+ between words so a + # reflow does not break it (G-074). Until 2026-10-07 this pinned "GitHub is a CNA ... so a + # CVE is requested from the advisory draft": true of GitHub, wrong for a hex.pm package, + # which the Erlang Ecosystem Foundation's CNA covers, so GitHub never assigned 0.10.1's. assert @policy =~ - ~r/GitHub\s+is\s+a\s+CVE\s+Numbering\s+Authority(\s+\(CNA\))?\s+for\s+repositories\s+it\s+hosts,\s+so\s+a\s+CVE\s+is\s+requested\s+from\s+the\s+advisory\s+draft/ + ~r/CVE\s+IDs\s+come\s+from\s+the\s+\[Erlang\s+Ecosystem\s+Foundation's\s+CNA\]\(https:\/\/cna\.erlef\.org\/\),\s+the\s+CVE\s+Numbering\s+Authority\s+for\s+every\s+active\s+package\s+on\s+hex\.pm/ + + assert @policy =~ ~r/added\s+to\s+the\s+draft\s+advisory\s+as\s+collaborators/ + assert @policy =~ "https://cna.erlef.org/maintainer-process" assert @policy =~ ~r/published\s+from\s+this\s+repository's\s+GitHub\s+Security\s+Advisories/ assert @policy =~ ~r/reaches\s+the\s+GitHub\s+Advisory\s+Database\s+and\s+OSV/