CVE-2026-58482
Network-AI: ApprovalInbox HTTP server has no authentication — anyone can approve pending agent actions
Network-AI, a TypeScript/Node.js multi-agent orchestrator, has a shipped, exported, documented feature called ApprovalInbox (lib/approval-inbox.ts). It is the network surface of the human-in-the-loop Approval Gate, which ApprovalGate uses to require explicit human approval for high-risk operations. The HTTP server it exposes has no authentication of any kind and sets Access-Control-Allow-Origin: * on every route, including the state-changing POST /approvals/:id/approve and /deny. As a result, in versions 5.0.0 through 5.12.1, any party who can send an HTTP request to the inbox port — a co-located process, a container/SSRF on the same host, a remote client when the operator binds a non-loopback address, or any website the operator visits in a browser (via the wildcard CORS) — can enumerate pending approvals and approve them, defeating the entire human-in-the-loop control and causing the gated high-risk action (e.g. a shell command the agent was holding for review) to execute without consent. This issue is fixed in v5.12.2. ApprovalInbox now accepts a secret option. When set, the mutating endpoints POST /:id/approve and POST /:id/deny require an Authorization: Bearer <secret> header, validated in constant time with crypto.timingSafeEqual. startServer() already binds to 127.0.0.1 by default; operators exposing the inbox on a network must set a secret.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- None
- User interaction
- Required
What an attacker can affect
- Confidentiality
- Low
- Integrity
- High
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
5.9
Network-AI: ApprovalInbox HTTP server has no authentication — anyone can approve pending agent actions
Network-AI, a TypeScript/Node.js multi-agent orchestrator, has a shipped, exported, documented feature called ApprovalInbox (lib/approval-inbox.ts). It is the network surface of the human-in-the-loop Approval Gate, which ApprovalGate uses to require explicit human approval for high-risk operations. The HTTP server it exposes has no authentication of any kind and sets Access-Control-Allow-Origin: * on every route, including the state-changing POST /approvals/:id/approve and /deny. As a result, in versions 5.0.0 through 5.12.1, any party who can send an HTTP request to the inbox port — a co-located process, a container/SSRF on the same host, a remote client when the operator binds a non-loopback address, or any website the operator visits in a browser (via the wildcard CORS) — can enumerate pending approvals and approve them, defeating the entire human-in-the-loop control and causing the gated high-risk action (e.g. a shell command the agent was holding for review) to execute without consent. This issue is fixed in v5.12.2. ApprovalInbox now accepts a secret option. When set, the mutating endpoints POST /:id/approve and POST /:id/deny require an Authorization: Bearer <secret> header, validated in constant time with crypto.timingSafeEqual. startServer() already binds to 127.0.0.1 by default; operators exposing the inbox on a network must set a secret.
- Record
CVE-2026-58482- CVSS 3.1
- 5.9 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:H/A:N - Weakness
- CWE-352, CWE-862
- Updated
- 2026-11-02
EUVDEUVD-2026-46020
5.9
Network-AI, a TypeScript/Node.js multi-agent orchestrator, has a shipped, exported, documented feature called ApprovalInbox (lib/approval-inbox.ts). It is the network surface of the human-in-the-loop Approval Gate, which ApprovalGate uses to require explicit human approval for high-risk operations. The HTTP server it exposes has no authentication of any kind and sets Access-Control-Allow-Origin: * on every route, including the state-changing POST /approvals/:id/approve and /deny. As a result, in versions 5.0.0 through 5.12.1, any party who can send an HTTP request to the inbox port — a co-located process, a container/SSRF on the same host, a remote client when the operator binds a non-loopback address, or any website the operator visits in a browser (via the wildcard CORS) — can enumerate pending approvals and approve them, defeating the entire human-in-the-loop control and causing the gated high-risk action (e.g. a shell command the agent was holding for review) to execute without consent. This issue is fixed in v5.12.2. ApprovalInbox now accepts a secret option. When set, the mutating endpoints POST /:id/approve and POST /:id/deny require an Authorization: Bearer <secret> header, validated in constant time with crypto.timingSafeEqual. startServer() already binds to 127.0.0.1 by default; operators exposing the inbox on a network must set a secret.
- Record
EUVD-2026-46020- CVSS 3.1
- 5.9 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:H/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-mxjx-28vx-xjjj
5.9
Network-AI: ApprovalInbox HTTP server has no authentication — anyone can approve pending agent actions
Summary
network-ai's ApprovalInbox (lib/approval-inbox.ts) is a shipped, exported, documented feature — "a web-accessible approval queue with REST API … and SSE streaming" (SECURITY.md). It is the network surface of the human-in-the-loop Approval Gate, which ApprovalGate uses to require explicit human approval for "high-risk operations (writes, shell commands, budget spend)" (SECURITY.md). The HTTP server it exposes has no authentication of any kind and sets Access-Control-Allow-Origin: * on every route, including the state-changing POST /approvals/:id/approve and /deny.
As a result, any party who can send an HTTP request to the inbox port — a co-located process, a container/SSRF on the same host, a remote client when the operator binds a non-loopback address, or any website the operator visits in a browser (via the wildcard CORS) — can enumerate pending approvals and approve them, defeating the entire human-in-the-loop control and causing the gated high-risk action (e.g. a shell command the agent was holding for review) to execute without consent.
This is the same vulnerability class the maintainer has already fixed twice on the MCP server (GHSA-fj4g-2p96-q6m3 missing auth; GHSA-j3vx-cx2r-pvg8 empty default secret) — the auxiliary ApprovalInbox server never received that hardening.
- Affected:
network-ai <= 5.11.0(current latest),lib/approval-inbox.ts—httpHandler()/routeRequest()/startServer().ApprovalInboxis public API (exported fromindex.ts:1126). - CWE: CWE-862 (Missing Authorization) + CWE-352 (Cross-Site Request Forgery, via wildcard CORS).
- CVSS v3.1 (proposed):
- Drive-by CSRF against the default
127.0.0.1deployment:AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:H/A:N= 5.9 Medium. - Direct request when the operator binds a non-loopback address (or local/SSRF reach):
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N= 8.1 High.
- Drive-by CSRF against the default
Details
No authentication on the request pipeline (lib/approval-inbox.ts)
httpHandler() sets a wildcard CORS policy and routes every request straight to routeRequest() with no auth check:
// lib/approval-inbox.ts:250-275
httpHandler() {
return (req, res) => {
...
res.setHeader('Access-Control-Allow-Origin', '*'); // 256 <-- wildcard CORS
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
if (req.method === 'OPTIONS') { res.writeHead(204); res.end(); return; } // preflight OK for any origin
...
this.routeRequest(req, res, subPath, url); // 273 <-- no token / secret / origin gate
};
}
routeRequest() exposes list + approve/deny with no credential check (default pathPrefix = /approvals):
// lib/approval-inbox.ts:369-405
routeRequest(req, res, subPath, url) {
if (subPath === '/' && req.method === 'GET') { // GET /approvals/ -> enumerate pending ids
this.sendJson(res, 200, this.list(status)); return;
}
...
const approveMatch = subPath.match(/^\/([a-f0-9]+)\/approve$/); // POST /approvals/:id/approve
if (approveMatch && req.method === 'POST') {
this.readBody(req).then((body) => {
const approvedBy = typeof body.approvedBy === 'string' ? body.approvedBy : 'anonymous'; // defaults to 'anonymous'
const entry = this.approve(approveMatch[1], approvedBy, reason); // resolves the gate -> action proceeds
...
});
}
}
approve() resolves the pending promise that ApprovalGate is awaiting, so the gated action proceeds:
// lib/approval-inbox.ts:172-183 / 327-339
approve(id, approvedBy, reason) {
...
return this.resolve(id, 'approved', { approved: true, approvedBy, reason }); // promise -> {approved:true}
}
startServer() binds the handler (default…
- Record
GHSA-mxjx-28vx-xjjj- CVSS 3.1
- 5.9 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:H/A:N - Weakness
- CWE-352, CWE-862
- Updated
- 2026-11-02
NVD
5.9
Network-AI, a TypeScript/Node.js multi-agent orchestrator, has a shipped, exported, documented feature called ApprovalInbox (lib/approval-inbox.ts). It is the network surface of the human-in-the-loop Approval Gate, which ApprovalGate uses to require explicit human approval for high-risk operations. The HTTP server it exposes has no authentication of any kind and sets Access-Control-Allow-Origin: * on every route, including the state-changing POST /approvals/:id/approve and /deny. As a result, in versions 5.0.0 through 5.12.1, any party who can send an HTTP request to the inbox port — a co-located process, a container/SSRF on the same host, a remote client when the operator binds a non-loopback address, or any website the operator visits in a browser (via the wildcard CORS) — can enumerate pending approvals and approve them, defeating the entire human-in-the-loop control and causing the gated high-risk action (e.g. a shell command the agent was holding for review) to execute without consent. This issue is fixed in v5.12.2. ApprovalInbox now accepts a secret option. When set, the mutating endpoints POST /:id/approve and POST /:id/deny require an Authorization: Bearer <secret> header, validated in constant time with crypto.timingSafeEqual. startServer() already binds to 127.0.0.1 by default; operators exposing the inbox on a network must set a secret.
- Record
CVE-2026-58482- CVSS 3.1
- 5.9 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:H/A:N - Weakness
- CWE-352, CWE-862
- Updated
- 2026-11-02
OSV
5.9
Network-AI: ApprovalInbox HTTP server has no authentication — anyone can approve pending agent actions
Network-AI, a TypeScript/Node.js multi-agent orchestrator, has a shipped, exported, documented feature called ApprovalInbox (lib/approval-inbox.ts). It is the network surface of the human-in-the-loop Approval Gate, which ApprovalGate uses to require explicit human approval for high-risk operations. The HTTP server it exposes has no authentication of any kind and sets Access-Control-Allow-Origin: * on every route, including the state-changing POST /approvals/:id/approve and /deny. As a result, in versions 5.0.0 through 5.12.1, any party who can send an HTTP request to the inbox port — a co-located process, a container/SSRF on the same host, a remote client when the operator binds a non-loopback address, or any website the operator visits in a browser (via the wildcard CORS) — can enumerate pending approvals and approve them, defeating the entire human-in-the-loop control and causing the gated high-risk action (e.g. a shell command the agent was holding for review) to execute without consent. This issue is fixed in v5.12.2. ApprovalInbox now accepts a secret option. When set, the mutating endpoints POST /:id/approve and POST /:id/deny require an Authorization: Bearer <secret> header, validated in constant time with crypto.timingSafeEqual. startServer() already binds to 127.0.0.1 by default; operators exposing the inbox on a network must set a secret.
- Record
CVE-2026-58482- CVSS 3.1
- 5.9 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:H/A:N - Weakness
- CWE-352, CWE-862
- Updated
- 2026-11-02
OSVGHSA-mxjx-28vx-xjjj
5.9
Network-AI: ApprovalInbox HTTP server has no authentication — anyone can approve pending agent actions
Summary
network-ai's ApprovalInbox (lib/approval-inbox.ts) is a shipped, exported, documented feature — "a web-accessible approval queue with REST API … and SSE streaming" (SECURITY.md). It is the network surface of the human-in-the-loop Approval Gate, which ApprovalGate uses to require explicit human approval for "high-risk operations (writes, shell commands, budget spend)" (SECURITY.md). The HTTP server it exposes has no authentication of any kind and sets Access-Control-Allow-Origin: * on every route, including the state-changing POST /approvals/:id/approve and /deny.
As a result, any party who can send an HTTP request to the inbox port — a co-located process, a container/SSRF on the same host, a remote client when the operator binds a non-loopback address, or any website the operator visits in a browser (via the wildcard CORS) — can enumerate pending approvals and approve them, defeating the entire human-in-the-loop control and causing the gated high-risk action (e.g. a shell command the agent was holding for review) to execute without consent.
This is the same vulnerability class the maintainer has already fixed twice on the MCP server (GHSA-fj4g-2p96-q6m3 missing auth; GHSA-j3vx-cx2r-pvg8 empty default secret) — the auxiliary ApprovalInbox server never received that hardening.
- Affected:
network-ai <= 5.11.0(current latest),lib/approval-inbox.ts—httpHandler()/routeRequest()/startServer().ApprovalInboxis public API (exported fromindex.ts:1126). - CWE: CWE-862 (Missing Authorization) + CWE-352 (Cross-Site Request Forgery, via wildcard CORS).
- CVSS v3.1 (proposed):
- Drive-by CSRF against the default
127.0.0.1deployment:AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:H/A:N= 5.9 Medium. - Direct request when the operator binds a non-loopback address (or local/SSRF reach):
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N= 8.1 High.
- Drive-by CSRF against the default
Details
No authentication on the request pipeline (lib/approval-inbox.ts)
httpHandler() sets a wildcard CORS policy and routes every request straight to routeRequest() with no auth check:
// lib/approval-inbox.ts:250-275
httpHandler() {
return (req, res) => {
...
res.setHeader('Access-Control-Allow-Origin', '*'); // 256 <-- wildcard CORS
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
if (req.method === 'OPTIONS') { res.writeHead(204); res.end(); return; } // preflight OK for any origin
...
this.routeRequest(req, res, subPath, url); // 273 <-- no token / secret / origin gate
};
}
routeRequest() exposes list + approve/deny with no credential check (default pathPrefix = /approvals):
// lib/approval-inbox.ts:369-405
routeRequest(req, res, subPath, url) {
if (subPath === '/' && req.method === 'GET') { // GET /approvals/ -> enumerate pending ids
this.sendJson(res, 200, this.list(status)); return;
}
...
const approveMatch = subPath.match(/^\/([a-f0-9]+)\/approve$/); // POST /approvals/:id/approve
if (approveMatch && req.method === 'POST') {
this.readBody(req).then((body) => {
const approvedBy = typeof body.approvedBy === 'string' ? body.approvedBy : 'anonymous'; // defaults to 'anonymous'
const entry = this.approve(approveMatch[1], approvedBy, reason); // resolves the gate -> action proceeds
...
});
}
}
approve() resolves the pending promise that ApprovalGate is awaiting, so the gated action proceeds:
// lib/approval-inbox.ts:172-183 / 327-339
approve(id, approvedBy, reason) {
...
return this.resolve(id, 'approved', { approved: true, approvedBy, reason }); // promise -> {approved:true}
}
startServer() binds the handler (default…
- Record
GHSA-mxjx-28vx-xjjj- CVSS 3.1
- 5.9 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:H/A:N - Weakness
- CWE-352, CWE-862
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
network-ainpm |
5.0.0 to 5.12.1 | 5.12.2 |
network-ainpm |
5.0.0 up to 5.12.2 | 5.12.2 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-58482 is a medium vulnerability (CVSS 5.9) in Jovancoding Network-ai, published June 19, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.20%, the 9th percentile. Fixed in network-ai 5.12.2.
References
github.com/Jovancoding/Network-AI/security/advisories/GHSA-mxjx-28vx-xjjj
github.com/Jovancoding/Network-AI/commit/a59c13a1f0ce0e8a0779a90343eef92fac5ab4c3
github.com/Jovancoding/Network-AI/releases/tag/v5.12.2
github.com/advisories/GHSA-mxjx-28vx-xjjj
github.com/CVEProject/cvelistV5/tree/main/cves/2026/58xxx/CVE-2026-58482.json
nvd.nist.gov/vuln/detail/CVE-2026-58482
github.com/Jovancoding/Network-AI
Left out here: the rest of 2 source descriptions. The JSON record has them.