Skip to content

Commit 56791e2

Browse files
author
jovanSAPFIONEER
committed
Security: fix GHSA-m4jg-6w3q-gm86 (ApprovalInbox auth/CORS) and GHSA-3jf7-33vc-hgf4 (APSAdapter fail-closed verification); bump to v5.13.4
- lib/approval-inbox.ts: gate entire routeRequest() pipeline behind checkAuth(), replace wildcard CORS with allowedOrigins allowlist - adapters/aps-adapter.ts: initialize() throws when verificationMode is local (default) with no verifySignature; verifyDelegation() fails closed instead of accepting any non-empty signature - test-phase17.ts (13 tests) + test-adapters.ts APS regression test; full suite 3,388/3,388 passing, tsc clean - scripts/blackboard.py: corrected header comment to document env-scoped data dir I/O (SkillSpector finding) - CHANGELOG.md, SECURITY.md, .github/SECURITY.md, docs: version bump + advisory writeups + test count updates
1 parent 42edb6b commit 56791e2

24 files changed

Lines changed: 323 additions & 49 deletions

.github/SECURITY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ Network-AI includes built-in security features:
9090
- **VirusTotal**: Benign (0/64 engines)
9191
- **OpenClaw Scanner**: Benign, HIGH CONFIDENCE
9292
- **GHSA-j3vx-cx2r-pvg8** (CWE-346, High, CVSS 7.6) — Unauthenticated Cross-Origin MCP Tool Invocation via Empty Default Secret — **Fixed in v5.4.5**. SSE server now requires a non-empty secret at startup; CORS restricted to localhost origins only. Reported by 232-323 and min8282.
93+
- **GHSA-m4jg-6w3q-gm86** (CWE-862, CWE-352, High) — `ApprovalInbox` GET read routes (`/`, `/stats`, `/sse`, `/:id`) remained unauthenticated and served a hardcoded wildcard `Access-Control-Allow-Origin: *` even when a `secret` was configured — an incomplete fix for GHSA-mxjx-28vx-xjjj, which only gated the two POST mutating routes. **Fixed in v5.13.4**`checkAuth()` now gates the entire route-dispatch pipeline uniformly; the wildcard CORS header was replaced with an explicit `allowedOrigins` allowlist (no header sent unless the request's `Origin` matches an allowlisted entry; matched origin is echoed back, never `*`). Reported by sec-reex.
94+
- **GHSA-3jf7-33vc-hgf4** (CWE-347, High, CVSS 8.6) — `APSAdapter`'s default `verificationMode: 'local'` treated any non-empty `signature` string as a valid cryptographic signature when no `verifySignature` callback was configured (the documented canonical `new APSAdapter()` + `initialize({})` setup), allowing a forged delegation to obtain a signed `SHELL_EXEC` permission-grant token with no authentication. **Fixed in v5.13.4**`initialize()` now throws if `verificationMode` is `'local'` and no `verifySignature` callback is supplied; `verifyDelegation()`'s fallback now returns `false` instead of a length check, failing closed as defense in depth.
9395
- **ClawHub Security Scanner** (v5.4.5): 4 Notes acknowledged and mitigated — ASI01 (agent goal hijack, by design: Orchestrator skill decomposes into 3 sub-tasks; SKILL.md documents when to enable/disable), ASI03 (advisory token identity, by design: tokens explicitly marked advisory, separate platform auth required), ASI06 (persistent context poisoning, by design: `_validate_context()` injection detection, SKILL.md warns against storing secrets, clear `data/` between projects), ASI07 (inter-agent communication boundary, by design: all inter-agent messaging is host platform's responsibility, documented in SKILL.md). These Notes reflect inherent design characteristics and will recur on future scans; the documented controls are the mitigation.- **ClawHub Security Scanner** (v5.5.2): ASI03 grant-token integrity — `check_permission.py` now HMAC-SHA256 signs each grant (`_sig` field); `validate_token.py` verifies before accepting. Signing key auto-generated at `data[/<env>]/.signing_key`. Zero new deps (stdlib `hmac`+`hashlib`). **Fixed in v5.5.2**.- **CodeQL**: v4.3.2 clean — A2A bearer tokens transmitted only via `Authorization` header; no URL embedding; streaming paths carry no credential material; `AbortController` guards prevent hanging fetch calls; CLI layer adds no new network surface (fully in-process); CWE-367 TOCTOU alerts #86/#87 resolved — `audit tail` and CLI test now open fd first and use `fs.fstatSync(fd)` instead of `fs.statSync(filename)`
9496
- **CodeQL** (historical): v3.3.0 — all fixable alerts resolved; unused imports cleaned; false-positive detection patterns dismissed; v3.4.0 clean; v3.4.1 — #65#68 HIGH (insecure temporary file) resolved via `path.resolve()` sanitization and `mode: 0o700` directory permissions
9597
- **Snyk**: All High/Medium findings resolved in v3.0.3

.github/copilot-instructions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Project Overview
44

5-
Network-AI is a TypeScript/Node.js multi-agent orchestrator — shared state, guardrails, budgets, and cross-framework coordination (v5.13.0). 3,373 tests across 37 suites.
5+
Network-AI is a TypeScript/Node.js multi-agent orchestrator — shared state, guardrails, budgets, and cross-framework coordination (v5.13.4). 3,388 tests across 38 suites.
66

77
## Architecture
88

ARCHITECTURE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Architecture
22

3-
Network-AI v5.13.0 — TypeScript/Node.js multi-agent orchestrator with 29 adapters, 3,373 tests, 78+ modules.
3+
Network-AI v5.13.4 — TypeScript/Node.js multi-agent orchestrator with 29 adapters, 3,388 tests, 78+ modules.
44

55
> **Two governance layers.** Policy engines govern *what an agent may do* before it acts (pre-wire tool gating). Network-AI adds the layer underneath — **model-interaction lifecycle governance**: when a frontier model returns a classifier refusal, the `GovernedModelGateway` audits it, falls over to another model, reprices the retry with fallback credit, hands off thinking blocks, and accounts the cost — one governed, budgeted, audited call. The two layers are complementary.
66

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,22 @@ All notable changes to Network-AI will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [5.13.4] - 2026-07-05
9+
10+
### Security
11+
- **`ApprovalInbox` GET read routes remain unauthenticated and wildcard-CORS after the GHSA-mxjx-28vx-xjjj fix** ([GHSA-m4jg-6w3q-gm86](https://github.com/Jovancoding/Network-AI/security/advisories/GHSA-m4jg-6w3q-gm86), CWE-862, CWE-352, High) — the v5.12.2 `secret` / `checkAuth()` gate covered only the two mutating routes (`POST /approve`, `POST /deny`), leaving `GET /`, `GET /stats`, `GET /sse`, and `GET /:id` unauthenticated even when a `secret` was configured, disclosing queued high-risk action content (command strings, file paths, justifications). The handler also hardcoded `Access-Control-Allow-Origin: *`.
12+
- **Fixed**: `checkAuth()` now gates the entire `routeRequest()` pipeline before route dispatch, covering every route uniformly.
13+
- **Fixed**: removed the hardcoded wildcard CORS header; added a new `allowedOrigins?: string[]` option on `ApprovalInboxOptions` — no `Access-Control-Allow-Origin` header is sent unless the request's `Origin` exactly matches an allowlisted entry, and the matched origin is echoed back (never `*`).
14+
- Reported by sec-reex via private security advisory.
15+
- Regression coverage: `test-phase17.ts` (13 tests) — read-route auth gating, correct/incorrect token handling, backward compatibility (no secret configured), and CORS allowlist behavior.
16+
- **`APSAdapter` default local verifier accepts any non-empty signature** ([GHSA-3jf7-33vc-hgf4](https://github.com/Jovancoding/Network-AI/security/advisories/GHSA-3jf7-33vc-hgf4), CWE-347, High, CVSS 8.6) — with the default `verificationMode: 'local'` and no caller-supplied `verifySignature` callback (the documented canonical `new APSAdapter()` + `initialize({})` setup), `verifyDelegation()` treated **any non-empty string** as a valid cryptographic signature. A forged delegation with an arbitrary `signature` and `scope: ['shell:exec']` could be registered into `AuthGuardian` as trusted and used to obtain a signed `SHELL_EXEC` permission-grant token with no authentication at all.
17+
- **Fixed**: `initialize()` now fails closed — it throws if `verificationMode` is `'local'` (the default) and no `verifySignature` callback is configured, forcing an explicit BYOC cryptographic verifier.
18+
- **Fixed**: the fallback branch of `verifyDelegation()` now returns `false` instead of `delegation.signature.length > 0`, so an unverified delegation is rejected as defense in depth even if the constructor guard is bypassed.
19+
- Regression coverage: `test-adapters.ts` — asserts `initialize({})` throws in default local mode, and that all existing BYOC/custom-verifier trust-mapping behavior is unaffected.
20+
21+
### Fixed
22+
- **SkillSpector Intent-Code Divergence**`scripts/blackboard.py` header comment claimed I/O was scoped to `swarm-blackboard.md` / `data/pending_changes/<id>.json` without mentioning that `NETWORK_AI_ENV` / `--env` redirect these under `data/<env>/`. Reworded to document the env-scoped path resolution accurately.
23+
824
## [5.13.3] - 2026-06-26
925

1026
### Fixed

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Network-AI is a TypeScript/Node.js multi-agent orchestrator — shared state, gu
1111
```bash
1212
npm install # Install dependencies
1313
npx tsc --noEmit # Type-check (zero errors expected)
14-
npm run test:all # Run all 3,373 tests across 37 suites
14+
npm run test:all # Run all 3,388 tests across 38 suites
1515
npm test # Core orchestrator tests only
1616
npm run test:security # Security module tests
1717
npm run test:adapters # All 29 adapter tests

CODEX.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Network-AI is a TypeScript/Node.js multi-agent orchestrator — shared state, gu
1111
```bash
1212
npm install # Install dependencies
1313
npx tsc --noEmit # Type-check (zero errors expected)
14-
npm run test:all # Run all 3,373 tests across 37 suites
14+
npm run test:all # Run all 3,388 tests across 38 suites
1515
npm test # Core orchestrator tests only
1616
npm run test:security # Security module tests
1717
npm run test:adapters # All 29 adapter tests

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Unsolicited PRs without a linked, approved issue will be closed.
4141
2. Implement your change with tests
4242
3. Run the full test suite:
4343
```bash
44-
npm run test:all # 3,373 tests across 37 suites
44+
npm run test:all # 3,388 tests across 38 suites
4545
npx tsc --noEmit
4646
```
4747
4. Open a PR referencing the approved issue

ENTERPRISE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ Network-AI follows [Semantic Versioning](https://semver.org/):
106106

107107
### Stability Signals
108108

109-
- 3,373 passing assertions across 37 suites
109+
- 3,388 passing assertions across 38 suites
110110
- Deterministic scoring — no random outcomes in permission evaluation or budget enforcement
111111
- CI runs on every push and every PR
112112
- All examples ship with the repo and run without mocking

INTEGRATION_GUIDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ Run these before declaring the integration production-ready:
496496
- [ ] `npx ts-node test-phase4.ts` — 147 behavioral tests pass
497497
- [ ] `npx ts-node test-qa.ts` — 67 QA orchestrator tests pass
498498
- [ ] `npx ts-node test-phase7.ts` — 94 Phase 7 tests pass (hooks, flow control, composer, semantic search)
499-
- [ ] `npm run test:all` — all 3,373 tests pass across 37 suites
499+
- [ ] `npm run test:all` — all 3,388 tests pass across 38 suites
500500
- [ ] `npm run demo -- --08` runs to completion in < 10 seconds
501501

502502
### Race Condition Safety

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
[![Website](https://img.shields.io/badge/website-network--ai.org-4b9df2?style=flat&logo=web&logoColor=white)](https://network-ai.org/)
66
[![CI](https://github.com/Jovancoding/Network-AI/actions/workflows/ci.yml/badge.svg)](https://github.com/Jovancoding/Network-AI/actions/workflows/ci.yml)
77
[![CodeQL](https://github.com/Jovancoding/Network-AI/actions/workflows/codeql.yml/badge.svg)](https://github.com/Jovancoding/Network-AI/actions/workflows/codeql.yml)
8-
[![Release](https://img.shields.io/badge/release-v5.13.3-blue.svg)](https://github.com/Jovancoding/Network-AI/releases)
8+
[![Release](https://img.shields.io/badge/release-v5.13.4-blue.svg)](https://github.com/Jovancoding/Network-AI/releases)
99
[![npm](https://img.shields.io/npm/dw/network-ai.svg?label=npm%20downloads)](https://www.npmjs.com/package/network-ai)
10-
[![Tests](https://img.shields.io/badge/tests-3373%20passing-brightgreen.svg)](#testing)
10+
[![Tests](https://img.shields.io/badge/tests-3388%20passing-brightgreen.svg)](#testing)
1111
[![Adapters](https://img.shields.io/badge/frameworks-29%20supported-blueviolet.svg)](#adapter-system)
1212
[![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE)
1313
[![Socket](https://socket.dev/api/badge/npm/package/network-ai)](https://socket.dev/npm/package/network-ai/overview)
@@ -542,7 +542,7 @@ npm run test:phase9 # Agent runtime, console, strategy agent
542542
npm run test:phase12 # Context Throttler, Partition Planner, Coverage Gate, Route Classifier
543543
```
544544

545-
**3,373 passing assertions across 37 test suites** (`npm run test:all`):
545+
**3,388 passing assertions across 38 test suites** (`npm run test:all`):
546546

547547
| Suite | Assertions | Covers |
548548
|---|---|---|
@@ -579,8 +579,9 @@ npm run test:phase12 # Context Throttler, Partition Planner, Coverage Gate,
579579
| `test-claim-verifier.ts` | 50 | ClaimVerifier: receipt generation/tamper/expiry, corroborated/unsupported/undisclosed, trust decay/reset/DoS protection |
580580
| `test-phase13.ts` | 58 | ESM dual-build config, McpStreamableServer dispatch + resources + prompts, PhasePipeline checkpoint/resume/clear, SemanticMemory save/load/autoSave/clearPersisted |
581581
| `test-phase14.ts` | 52 | Model lifecycle governance: `GovernedModelGateway` refusal→fallback, `ModelBudget` credit repricing, `RefusalTelemetry`, Anthropic Messages adapter |
582-
| `test-phase15.ts` | 31 | Orchestration resilience: `RetryBudget`, per-sub-agent fallback in `FanOutFanIn` + `TeamRunner`, `EffortPolicy` |
582+
| `test-phase15.ts` | 32 | Orchestration resilience: `RetryBudget`, per-sub-agent fallback in `FanOutFanIn` + `TeamRunner`, `EffortPolicy` |
583583
| `test-phase16.ts` | 21 | `ThinkingBlockManager` lifecycle + reasoning-extraction guard, OWASP Agentic Top 10 coverage matrix |
584+
| `test-phase17.ts` | 13 | `ApprovalInbox` GHSA-m4jg-6w3q-gm86 fix: read-route auth gating, token validation, backward compatibility, CORS allowlist |
584585
| `test.ts` | 39 | Core orchestrator smoke tests |
585586

586587
---

0 commit comments

Comments
 (0)