Skip to content

Commit 34e25e1

Browse files
author
jovanSAPFIONEER
committed
fix: resolve all remaining CodeQL alerts and pin action SHAs
- ci.yml, codeql.yml, dependabot-auto-merge.yml: pin all actions to full commit SHA (Pinned-Dependencies fix) - codeql.yml: add permissions: read-all at workflow level (Token-Permissions fix) - locked-blackboard.ts: remove final existsSync+readFileSync TOCTOU race; read directly and handle ENOENT; remove unused statSync import - security.ts: remove unused existsSync and writeFileSync imports - check_permission.py: remove always-true word_count>0 ternary (line 142, 156) - blackboard.py, swarm_guard.py, validate_token.py: add comments to bare empty-except blocks (py/empty-except fix) 315/315 tests pass
1 parent 6df6198 commit 34e25e1

16 files changed

+60
-53
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ jobs:
1919

2020
steps:
2121
- name: Checkout
22-
uses: actions/checkout@v6
22+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
2323

2424
- name: Setup Node.js ${{ matrix.node-version }}
25-
uses: actions/setup-node@v6
25+
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
2626
with:
2727
node-version: ${{ matrix.node-version }}
2828
cache: 'npm'
@@ -51,10 +51,10 @@ jobs:
5151

5252
steps:
5353
- name: Checkout
54-
uses: actions/checkout@v6
54+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
5555

5656
- name: Setup Node.js
57-
uses: actions/setup-node@v6
57+
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
5858
with:
5959
node-version: 20
6060
cache: 'npm'

.github/workflows/codeql.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ name: CodeQL Security Analysis
88
schedule:
99
- cron: '30 4 * * 1' # Every Monday at 04:30 UTC
1010

11+
permissions: read-all
12+
1113
jobs:
1214
analyze:
1315
name: Analyze (${{ matrix.language }})
@@ -24,18 +26,18 @@ jobs:
2426

2527
steps:
2628
- name: Checkout repository
27-
uses: actions/checkout@v6
29+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
2830

2931
- name: Initialize CodeQL
30-
uses: github/codeql-action/init@v4
32+
uses: github/codeql-action/init@9e907b5e64f6b83e7804b09294d44122997950d6 # v4
3133
with:
3234
languages: ${{ matrix.language }}
3335
queries: security-extended,security-and-quality
3436

3537
- name: Autobuild
36-
uses: github/codeql-action/autobuild@v4
38+
uses: github/codeql-action/autobuild@9e907b5e64f6b83e7804b09294d44122997950d6 # v4
3739

3840
- name: Perform CodeQL Analysis
39-
uses: github/codeql-action/analyze@v4
41+
uses: github/codeql-action/analyze@9e907b5e64f6b83e7804b09294d44122997950d6 # v4
4042
with:
4143
category: '/language:${{ matrix.language }}'

.github/workflows/dependabot-auto-merge.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
steps:
1414
- name: Fetch Dependabot metadata
1515
id: metadata
16-
uses: dependabot/fetch-metadata@v2
16+
uses: dependabot/fetch-metadata@21025c705c08248db411dc16f3619e6b5f9ea21a # v2
1717
with:
1818
github-token: ${{ secrets.GITHUB_TOKEN }}
1919

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ 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+
## [3.2.9] - 2026-02-19
9+
10+
### Fixed
11+
- **Pinned-Dependencies** -- all GitHub Actions in `ci.yml`, `codeql.yml`, and `dependabot-auto-merge.yml` pinned to full commit SHA (Scorecard supply-chain requirement)
12+
- **Token-Permissions** -- added `permissions: read-all` at workflow level in `codeql.yml`
13+
- **Remaining TOCTOU** -- removed final `existsSync` + `readFileSync` race in `locked-blackboard.ts`; now reads directly and handles `ENOENT`
14+
- **Unused imports** -- removed `existsSync`/`writeFileSync` from `security.ts` and `statSync` from `locked-blackboard.ts`
15+
- **py/redundant-comparison** -- removed always-true `word_count > 0` ternary in `check_permission.py` (guaranteed `>= 3` by earlier guard)
16+
- **py/empty-except** -- added explanatory comments to all bare `pass` except blocks in `blackboard.py`, `swarm_guard.py`, and `validate_token.py`
17+
818
## [3.2.8] - 2026-02-19
919

1020
### Fixed

README.md

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

55
[![CI](https://github.com/jovanSAPFIONEER/Network-AI/actions/workflows/ci.yml/badge.svg)](https://github.com/jovanSAPFIONEER/Network-AI/actions/workflows/ci.yml)
66
[![CodeQL](https://github.com/jovanSAPFIONEER/Network-AI/actions/workflows/codeql.yml/badge.svg)](https://github.com/jovanSAPFIONEER/Network-AI/actions/workflows/codeql.yml)
7-
[![Release](https://img.shields.io/badge/release-v3.2.8-blue.svg)](https://github.com/jovanSAPFIONEER/Network-AI/releases)
7+
[![Release](https://img.shields.io/badge/release-v3.2.9-blue.svg)](https://github.com/jovanSAPFIONEER/Network-AI/releases)
88
[![npm](https://img.shields.io/npm/dw/network-ai.svg?label=npm%20downloads)](https://www.npmjs.com/package/network-ai)
99
[![ClawHub](https://img.shields.io/badge/ClawHub-network--ai-orange.svg)](https://clawhub.ai/skills/network-ai)
1010
[![Node.js](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg)](https://nodejs.org)

SECURITY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Network-AI includes built-in security features:
3737

3838
- **VirusTotal**: Benign (0/64 engines)
3939
- **OpenClaw Scanner**: Benign, HIGH CONFIDENCE
40-
- **CodeQL**: v3.2.8 -- all HIGH alerts resolved (TOCTOU race conditions, bad HTML regex, missing regex anchor, Token-Permissions)
40+
- **CodeQL**: v3.2.9 -- all remaining HIGH/WARNING alerts resolved; actions SHA-pinned; unused imports removed
4141
- **Snyk**: All High/Medium findings resolved in v3.0.3
4242

4343
## Disclosure Policy

lib/locked-blackboard.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import {
2525
openSync,
2626
closeSync,
2727
writeSync,
28-
statSync,
2928
readdirSync
3029
} from 'fs';
3130
import { join, dirname } from 'path';
@@ -128,9 +127,8 @@ export class FileLock {
128127

129128
private ensureDir(): void {
130129
const dir = dirname(this.lockPath);
131-
if (!existsSync(dir)) {
132-
mkdirSync(dir, { recursive: true });
133-
}
130+
// recursive: true is idempotent — no existsSync check needed
131+
mkdirSync(dir, { recursive: true });
134132
}
135133

136134
/**
@@ -143,25 +141,26 @@ export class FileLock {
143141
const startTime = Date.now();
144142

145143
while (Date.now() - startTime < timeoutMs) {
146-
// Check for stale lock
147-
if (existsSync(this.lockPath)) {
148-
try {
149-
const lockData = JSON.parse(readFileSync(this.lockPath, 'utf-8'));
150-
const lockAge = Date.now() - new Date(lockData.acquired_at).getTime();
151-
152-
// If lock is stale, force release it
153-
if (lockAge > CONFIG.staleLockThresholdMs) {
154-
log.warn('Stale lock detected, force releasing', { lockAgeMs: lockAge });
155-
this.forceRelease();
156-
} else {
157-
// Lock is held by someone else, wait and retry
158-
this.sleep(CONFIG.lockRetryIntervalMs);
159-
continue;
160-
}
161-
} catch {
144+
// Check for stale lock — read directly to avoid existsSync+readFileSync TOCTOU
145+
try {
146+
const lockData = JSON.parse(readFileSync(this.lockPath, 'utf-8'));
147+
const lockAge = Date.now() - new Date(lockData.acquired_at).getTime();
148+
149+
// If lock is stale, force release it
150+
if (lockAge > CONFIG.staleLockThresholdMs) {
151+
log.warn('Stale lock detected, force releasing', { lockAgeMs: lockAge });
152+
this.forceRelease();
153+
} else {
154+
// Lock is held by someone else, wait and retry
155+
this.sleep(CONFIG.lockRetryIntervalMs);
156+
continue;
157+
}
158+
} catch (e: any) {
159+
if (e.code !== 'ENOENT') {
162160
// Corrupted lock file, remove it
163161
this.forceRelease();
164162
}
163+
// ENOENT: no lock file yet, fall through to create
165164
}
166165

167166
// Try to create lock file atomically

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "network-ai",
3-
"version": "3.2.8",
3+
"version": "3.2.9",
44
"description": "AI agent orchestration framework for TypeScript/Node.js - plug-and-play multi-agent coordination with 12 frameworks (LangChain, AutoGen, CrewAI, OpenAI Assistants, LlamaIndex, Semantic Kernel, Haystack, DSPy, Agno, MCP, OpenClaw). Built-in security, swarm intelligence, and agentic workflow patterns.",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

scripts/blackboard.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
import fcntl as _fcntl_import
5555
_fcntl = _fcntl_import
5656
except ImportError:
57-
pass
57+
pass # fcntl unavailable on Windows; file-based lock fallback is used instead
5858

5959
# Default blackboard location
6060
BLACKBOARD_PATH = Path(__file__).parent.parent / "swarm-blackboard.md"
@@ -130,7 +130,7 @@ def release(self) -> None:
130130

131131
self.lock_file.close()
132132
except Exception:
133-
pass
133+
pass # best-effort unlock; fd and marker cleaned up in finally
134134
finally:
135135
self.lock_file = None
136136
self.lock_marker = None

0 commit comments

Comments
 (0)