Every CVE Search/ Get API key

CVE-2026-58482

Network-AI: ApprovalInbox HTTP server has no authentication — anyone can approve pending agent actions

5.9 MediumFix available

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

0.20%Up 0.1 points since Jul 21, 2026
90%50%10%1%

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 MediumCVSS: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 MediumCVSS: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(). ApprovalInbox is public API (exported from index.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.1 deployment: 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.

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 MediumCVSS: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 MediumCVSS: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 MediumCVSS: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(). ApprovalInbox is public API (exported from index.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.1 deployment: 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.

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 MediumCVSS: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

Affected packages
PackageAffectedFixed
network-ai
npm
5.0.0 to 5.12.1
5.12.2
network-ai
npm
5.0.0 up to 5.12.2
5.12.2

History

History
RecordedChangedSources
first indexedCVE 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

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open