Skip to content

Commit 353dc63

Browse files
JanniePSwarmdo
andcommitted
fix(security): crypto-strong session/terminal IDs in cli + mcp — bump 1.3.5
Replaces Math.random()-based ID generation (js/insecure-randomness) with crypto.randomBytes — predictable session/terminal IDs are guessable and enable session-fixation/hijacking: - cli/mcp-tools/session-tools.ts ×2 (session create + rotate): the session-${Date.now()}-${Math.random().toString(36).slice(2,8)} id → randomBytes(6).toString('hex'). - cli/mcp-tools/terminal-tools.ts ×2 (term ids): same swap. - mcp/session-manager.ts generateSessionId(): third copy of the session-id pattern (batch 1 fixed the v3/mcp + @swarmdo/shared copies; this @swarmdo/mcp one was missed) → randomBytes(6).toString('hex'). randomBytes(6) = 48 bits hex (12 chars), stronger than the old ~31-bit base36 slice. Added 'node:crypto' imports. Build clean; tests pass: cli session/ terminal-encryption (14) + mcp-tools-deep (107), mcp suite (65). Versioning: cli was at 1.3.2 while umbrella advanced to 1.3.4 (batches 7-8 bumped the umbrella for other bundled packages but not cli) — resynced the cli+umbrella+bridge lockstep to 1.3.5; mcp 3.0.0-alpha.11. 5 insecure-randomness alerts; ~15 first-party remain (other ID generators, next). Co-Authored-By: Swarmdo <maintainers@swarmdo.com>
1 parent 8090e30 commit 353dc63

8 files changed

Lines changed: 14 additions & 11 deletions

File tree

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": "swarmdo",
3-
"version": "1.3.4",
3+
"version": "1.3.5",
44
"description": "Swarmdo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration",
55
"main": "dist/index.js",
66
"type": "module",

swarmdo/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "swarmdo-bridge",
3-
"version": "1.3.4",
3+
"version": "1.3.5",
44
"private": true,
55
"description": "Swarmdo MCP-bridge + docker tooling (NOT published \u2014 the canonical `swarmdo` npm package is the repo root). Resolves the post-rename name collision where this wrapper and the root umbrella both became `swarmdo`.",
66
"main": "bin/swarmdo.js",

v3/@swarmdo/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@swarmdo/cli",
3-
"version": "1.3.2",
3+
"version": "1.3.5",
44
"type": "module",
55
"description": "Swarmdo CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
66
"main": "dist/src/index.js",

v3/@swarmdo/cli/src/mcp-tools/session-tools.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import { existsSync, readFileSync, readdirSync, unlinkSync, statSync, writeFileSync } from 'node:fs';
88
import { join } from 'node:path';
9+
import { randomBytes } from 'node:crypto';
910
import { type MCPTool, getProjectCwd } from './types.js';
1011
import {
1112
mkdirRestricted,
@@ -162,7 +163,7 @@ export const sessionTools: MCPTool[] = [
162163
if (!v.valid) return { success: false, error: v.error };
163164
}
164165

165-
const sessionId = `session-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
166+
const sessionId = `session-${Date.now()}-${randomBytes(6).toString('hex')}`;
166167

167168
// Load related data based on options
168169
const data = loadRelatedStores({
@@ -533,7 +534,7 @@ export const sessionTools: MCPTool[] = [
533534
let parsed: SessionRecord;
534535
try { parsed = JSON.parse(readFileSync(inputPath, 'utf-8')); }
535536
catch (e) { return { error: `Invalid session JSON: ${(e as Error).message}` }; }
536-
const newId = `session-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
537+
const newId = `session-${Date.now()}-${randomBytes(6).toString('hex')}`;
537538
const stats = parsed.stats || { tasks: 0, agents: 0, memoryEntries: 0, totalSize: 0 };
538539
const session: SessionRecord = {
539540
sessionId: newId,

v3/@swarmdo/cli/src/mcp-tools/terminal-tools.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import { type MCPTool, getProjectCwd } from './types.js';
88
import { existsSync } from 'node:fs';
9+
import { randomBytes } from 'node:crypto';
910
import {
1011
mkdirRestricted,
1112
readFileMaybeEncrypted,
@@ -110,7 +111,7 @@ export const terminalTools: MCPTool[] = [
110111
if (!vEnv.valid) return { success: false, error: vEnv.error };
111112

112113
const store = loadTerminalStore();
113-
const id = `term-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
114+
const id = `term-${Date.now()}-${randomBytes(6).toString('hex')}`;
114115

115116
const session: TerminalSession = {
116117
id,
@@ -168,7 +169,7 @@ export const terminalTools: MCPTool[] = [
168169

169170
if (!session) {
170171
// Create default session
171-
const id = `term-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
172+
const id = `term-${Date.now()}-${randomBytes(6).toString('hex')}`;
172173
session = {
173174
id,
174175
name: 'Default Terminal',

v3/@swarmdo/mcp/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@swarmdo/mcp",
3-
"version": "3.0.0-alpha.10",
3+
"version": "3.0.0-alpha.11",
44
"type": "module",
55
"description": "Standalone MCP (Model Context Protocol) server - stdio/http/websocket transports, connection pooling, tool registry",
66
"main": "dist/index.js",

v3/@swarmdo/mcp/src/session-manager.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
import { EventEmitter } from 'events';
8+
import { randomBytes } from 'node:crypto';
89
import type {
910
MCPSession,
1011
SessionState,
@@ -313,7 +314,7 @@ export class SessionManager extends EventEmitter {
313314
}
314315

315316
private generateSessionId(): string {
316-
return `session-${++this.sessionCounter}-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`;
317+
return `session-${++this.sessionCounter}-${Date.now()}-${randomBytes(6).toString('hex')}`;
317318
}
318319

319320
clearAll(): void {

0 commit comments

Comments
 (0)