{"id":"GHSA-r78r-rwrf-rjwp","revision":null,"records":[{"revision":"d328a0a280b74ec0a2fe80d088955a4f","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-48814","aliases":[],"title":"Network-AI:  Empty default secret still authorizes all requests (Incomplete fix for CVE-2026-46701)","description":"Network-AI is a TypeScript/Node.js multi-agent orchestrator. In versions 5.7.1 and earlier, the MCP SSE server allows unauthenticated cross-origin MCP tool invocation due to an empty default secret. This issue was partially addressed by CVE-2026-46701 in version 5.4.5 by closing the CORS flaw (with Access-Control-Allow-Origin now set only for localhost origins), but the empty-default-secret flaw described in the title remained: the SSE MCP server still defaulted to an empty secret, _isAuthorized() still returned true when the secret was empty, and a non-loopback bind only produced a warning. As a result, the server still ran fully unauthenticated by default. Any non-browser caller (for example, curl, SSRF, or a 0.0.0.0 bind) could invoke all 22 MCP tools (config_set, agent_spawn, blackboard_write, token_*) with no credentials. This issue was fixed in version 5.7.2.","state":0,"publishedAt":"2026-06-17T19:42:30.415+00:00","modifiedAt":"2026-06-18T19:43:01.315+00:00","affected":[{"ecosystem":"Vendor product","name":"Network-AI","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"Jovancoding\",\n                    \"product\": \"Network-AI\",\n                    \"versions\": [\n                        {\n                            \"version\": \"< 5.7.2\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","score":9.1,"severity":"CRITICAL"}],"references":["https://github.com/Jovancoding/Network-AI/security/advisories/GHSA-r78r-rwrf-rjwp","https://github.com/Jovancoding/Network-AI/releases/tag/v5.7.2","https://github.com/advisories/GHSA-j3vx-cx2r-pvg8"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-48814","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-48814","identifiers":["CVE-2026-48814"]},"retained":false,"historicalAffected":[]},{"revision":"ffdf82c7c34249e78cf5f8ad6edc5dce","observedAt":"2026-11-07T11:30:52.43+00:00","statement":{"source":"euvd","id":"EUVD-2026-37787","aliases":["CVE-2026-48814","GHSA-r78r-rwrf-rjwp"],"title":"Network-AI is a TypeScript/Node.js multi-agent orchestrator. In versions 5.7.1 and earlier, the MCP SSE server allows unauthenticated cross-origin MCP tool invocation due to an empty default secret. This issue was partially addressed by CVE…","description":"Network-AI is a TypeScript/Node.js multi-agent orchestrator. In versions 5.7.1 and earlier, the MCP SSE server allows unauthenticated cross-origin MCP tool invocation due to an empty default secret. This issue was partially addressed by CVE-2026-46701 in version 5.4.5 by closing the CORS flaw (with Access-Control-Allow-Origin now set only for localhost origins), but the empty-default-secret flaw described in the title remained: the SSE MCP server still defaulted to an empty secret, _isAuthorized() still returned true when the secret was empty, and a non-loopback bind only produced a warning. As a result, the server still ran fully unauthenticated by default. Any non-browser caller (for example, curl, SSRF, or a 0.0.0.0 bind) could invoke all 22 MCP tools (config_set, agent_spawn, blackboard_write, token_*) with no credentials. This issue was fixed in version 5.7.2.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","score":9.1,"severity":null}],"references":["https://github.com/Jovancoding/Network-AI/security/advisories/GHSA-r78r-rwrf-rjwp","https://github.com/Jovancoding/Network-AI/releases/tag/v5.7.2","https://github.com/advisories/GHSA-j3vx-cx2r-pvg8"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-37787","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Jun 17, 2026, 7:42:30 PM","dateUpdated":"Jun 18, 2026, 7:43:01 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2026-37787","identifiers":["EUVD-2026-37787","CVE-2026-48814","GHSA-r78r-rwrf-rjwp"]},"retained":false,"historicalAffected":[]},{"revision":"be9c2ff941b146929a5278ce3764ed2e","observedAt":"2026-10-27T13:11:53.172+00:00","statement":{"source":"nvd","id":"CVE-2026-48814","aliases":[],"title":"Network-AI is a TypeScript/Node.js multi-agent orchestrator. In versions 5.7.1 and earlier, the MCP SSE server allows unauthenticated cross-origin MCP tool invocation due to an empty default secret. This issue was partially addressed by CVE…","description":"Network-AI is a TypeScript/Node.js multi-agent orchestrator. In versions 5.7.1 and earlier, the MCP SSE server allows unauthenticated cross-origin MCP tool invocation due to an empty default secret. This issue was partially addressed by CVE-2026-46701 in version 5.4.5 by closing the CORS flaw (with Access-Control-Allow-Origin now set only for localhost origins), but the empty-default-secret flaw described in the title remained: the SSE MCP server still defaulted to an empty secret, _isAuthorized() still returned true when the secret was empty, and a non-loopback bind only produced a warning. As a result, the server still ran fully unauthenticated by default. Any non-browser caller (for example, curl, SSRF, or a 0.0.0.0 bind) could invoke all 22 MCP tools (config_set, agent_spawn, blackboard_write, token_*) with no credentials. This issue was fixed in version 5.7.2.","state":0,"publishedAt":"2026-06-17T20:17:22.26+00:00","modifiedAt":"2026-10-25T23:10:00.167+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","score":9.1,"severity":"CRITICAL"}],"references":["https://github.com/Jovancoding/Network-AI/releases/tag/v5.7.2","https://github.com/Jovancoding/Network-AI/security/advisories/GHSA-r78r-rwrf-rjwp","https://github.com/advisories/GHSA-j3vx-cx2r-pvg8"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-48814","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-306"],"productCriteria":[],"sourceDates":{"published":"2026-06-17T20:17:22.260","lastModified":"2026-10-25T23:10:00.167"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2026-48814","identifiers":["CVE-2026-48814"]},"retained":false,"historicalAffected":[]},{"revision":"98259ff5f66f4621849cef7cdd73d726","observedAt":"2026-10-24T13:17:17.793+00:00","statement":{"source":"osv","id":"GHSA-r78r-rwrf-rjwp","aliases":["CVE-2026-48814"],"title":"Network-AI: CVE-2026-46701 fix incomplete — empty default secret still authorizes all requests","description":"## Advisory / Disclosure\n\n# Network-AI — CVE-2026-46701 fix is incomplete: the \"Empty Default Secret\" unauth path survives\n\n**Target:** Jovancoding/Network-AI (npm `network-ai`), **latest v5.7.1**\n**Status:** the advisory (\"Unauthenticated Cross-Origin MCP Tool Invocation via Empty\nDefault Secret\") named three flaws. The fix (5.4.5) closed the **CORS** flaw\n(`Access-Control-Allow-Origin` is now set only for localhost origins), but left the\n**empty-default-secret** flaw the title is about: the SSE MCP server still defaults to an\nempty secret, `_isAuthorized()` still returns `true` when the secret is empty, and a\nnon-loopback bind only **warns**. So the server still runs **fully unauthenticated by\ndefault** — any non-browser caller (curl, SSRF, or a `0.0.0.0` bind) can invoke all 22 MCP\ntools (`config_set`, `agent_spawn`, `blackboard_write`, `token_*`) with no credentials.\n**Class:** CWE-306/CWE-862 Missing Authentication — incomplete fix.\n**Methodology:** M1 incomplete-fix audit (anchor = the 5.4.5 fix; sibling-walk on latest v5.7.1, executed).\n**Severity:** High (matches parent; the browser amplifier is removed, so exploitation now\nneeds non-browser reach — SSRF or a non-loopback bind, which the fix only warns about).\n\n## What the fix did and didn't do (verified on latest v5.7.1)\n| advisory flaw | latest v5.7.1 |\n|---|---|\n| wildcard CORS (`ACAO: *`) | **FIXED** — `lib/mcp-transport-sse.ts` sets `ACAO` only when `origin` matches `^https?://(localhost\\|127\\.0\\.0\\.1)(:\\d+)?$` |\n| empty default secret | **NOT FIXED** — `bin/mcp-server.ts`: `secret: process.env['NETWORK_AI_MCP_SECRET'] ?? ''` |\n| `_isAuthorized` open on empty secret | **NOT FIXED** — `if (!this._opts.secret) return true;` |\n| require secret / refuse unauth bind | **NOT DONE** — `listen()` only `process.stderr.write('… WARNING …')` on non-loopback bind, then listens anyway |\n\nThe advisory's remediation #1 (\"Require a non-empty secret at startup … `process.exit(1)`\")\nwas not implemented.\n\n## PoC (executed against the latest source, v5.7.1) — `poc/legend-networkai-empty-secret.ts`\nInstantiates the real `McpSseServer` from the latest `lib/` with a mock bridge and the\n**default (empty) secret**, then issues requests (run-log `poc/run-log.txt`):\n\n```\nPOST /mcp  no-auth, no-origin (curl/SSRF) -> HTTP 200, dispatched=true\n   body: {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{\"executed\":true,\"tool\":\"config_set\"}}\nPOST /mcp  Origin: evil.example.com        -> ACAO=undefined   (CORS half fixed)\n```\nThe no-auth request passes `_isAuthorized` and reaches `handleRPC` (tool dispatched) — i.e.\nunauthenticated tool invocation persists on the latest release; only the browser-CORS read\namplifier was removed.\n\nRun: from a v5.7.1 checkout, `npm i` then\n`npx ts-node --transpile-only poc/legend-networkai-empty-secret.ts`.\n\n## Recommended fix\nImplement the advisory's remediation #1: refuse to start SSE mode with an empty secret\n(unless `--stdio`), and/or change `_isAuthorized` to fail closed (an empty configured\nsecret should mean \"deny\", not \"allow\"). The CORS allowlist alone does not authenticate\nnon-browser callers.\n\n## Precondition / honesty\nWith CORS now localhost-only, the drive-by *browser* attack is mitigated. The residual\nrequires a non-browser path to the port: an SSRF on the host, or the operator binding to a\nnon-loopback address (Docker/remote), which the fix only warns about. The empty secret\nremains the shipped default and `_isAuthorized` still authorizes it.\n\n## Credits\n\n@Kai Aizen / @SnailSploit — https://snailsploit.com","state":0,"publishedAt":"2026-06-19T13:34:24+00:00","modifiedAt":"2026-07-08T08:29:23.5195845+00:00","affected":[{"ecosystem":"npm","name":"network-ai","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"5.7.2"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"CRITICAL"}],"references":["https://github.com/Jovancoding/Network-AI/security/advisories/GHSA-r78r-rwrf-rjwp","https://nvd.nist.gov/vuln/detail/CVE-2026-48814","https://github.com/Jovancoding/Network-AI","https://github.com/Jovancoding/Network-AI/releases/tag/v5.7.2","https://github.com/advisories/GHSA-j3vx-cx2r-pvg8"],"sourceUrl":"https://github.com/advisories/GHSA-r78r-rwrf-rjwp","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-r78r-rwrf-rjwp","identifiers":["GHSA-r78r-rwrf-rjwp","CVE-2026-48814"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-11-07T20:52:46.7845564+00:00","complete":true,"records":1769,"lastAttemptAt":"2026-11-07T20:52:46.7845564+00:00","lastSuccessAt":"2026-11-07T20:52:46.9707302+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:52:46.9707321+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-bb5c9d5a08063ef076042e33dd72a7d0ffa4c4487efdcf3106e29ba55ec2ad57-1766179264875bb4621a23ce4c6bcebec63fb794a16e35c2f5592f4ee300ee2e","complete":true,"records":420944,"lastAttemptAt":"2026-11-07T20:52:46.1142943+00:00","lastSuccessAt":"2026-11-07T20:52:46.0341312+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:52:46.1142943+00:00","snapshotPublishedAt":"2026-11-07T20:26:36+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-cbfb00168958467aaa6015d5230faa08","complete":true,"records":13633,"lastAttemptAt":"2026-11-07T21:04:54.6100336+00:00","lastSuccessAt":"2026-11-07T21:04:54.606+00:00","error":null,"lastVerifiedAt":"2026-11-07T21:04:54.606+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13685,"expectedIdentifiers":13685,"failedIdentifiers":0},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-11-07T20:52:46.7845564+00:00","complete":true,"records":1096,"lastAttemptAt":"2026-11-07T20:52:46.7845564+00:00","lastSuccessAt":"2026-11-07T20:52:47.1482288+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:52:47.1482303+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-b9464f9c589b4886928e7045b5ad1e11","complete":true,"records":13645,"lastAttemptAt":"2026-11-07T20:52:54.6850231+00:00","lastSuccessAt":"2026-11-07T20:52:54.68+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:52:54.68+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13685,"expectedIdentifiers":13685,"failedIdentifiers":0},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-0eb4d6dde62dffacd040ad992d4fd5a65cd7d0dc5f5f4cfa8b41967fc6f9ca5f","complete":true,"records":9914,"lastAttemptAt":"2026-11-07T20:52:46.6024506+00:00","lastSuccessAt":"2026-11-06T20:10:36.6450506+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:52:46.6024506+00:00","snapshotPublishedAt":"2026-11-06T20:02:57+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-fde804134ecdda0ddd5ff5c26ee1fff5a6fa659311f7ef2e51c6ad54964db0e2","complete":true,"records":1971,"lastAttemptAt":"2026-11-07T20:52:46.3552169+00:00","lastSuccessAt":"2026-11-06T19:03:17.0399903+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:52:46.3552169+00:00","snapshotPublishedAt":"2026-11-06T18:17:57+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-335633e78a15c9cde10a6025895b5617717087fb945489ae7e15d377bacf34a9","complete":true,"records":3055,"lastAttemptAt":"2026-11-07T20:52:46.7261257+00:00","lastSuccessAt":"2026-11-06T16:03:00.7615789+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:52:46.7261257+00:00","snapshotPublishedAt":"2026-11-06T16:02:48+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-40ad6183a951565ace1520a9b4d631e1d0bfb1d4bf7c5574c375032559f3ff53","complete":true,"records":231292,"lastAttemptAt":"2026-11-07T20:52:46.4923243+00:00","lastSuccessAt":"2026-11-07T10:29:00.4821259+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:52:46.4923243+00:00","snapshotPublishedAt":"2026-11-07T09:32:47+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}