shieldcortex 2.4.22 → 2.4.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/.next/standalone/dashboard/.next/BUILD_ID +1 -1
- package/dashboard/.next/standalone/dashboard/.next/build-manifest.json +2 -2
- package/dashboard/.next/standalone/dashboard/.next/prerender-manifest.json +3 -3
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +10 -10
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +10 -10
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +3 -3
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +6 -6
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +5 -5
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +5 -5
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +4 -4
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/page/react-loadable-manifest.json +3 -3
- package/dashboard/.next/standalone/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_25b1b286._.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.json +1 -1
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/0ba8a0e679bf5c40.js +842 -0
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/17348ec48b354115.css +3 -0
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/caa049bd46f24dd8.js +1 -0
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/cb7d5bff58e77e2c.js +9 -0
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/e007ff86847a4042.js +1 -0
- package/dist/api/visualization-server.d.ts.map +1 -1
- package/dist/api/visualization-server.js +154 -2
- package/dist/api/visualization-server.js.map +1 -1
- package/dist/cloud/sync.d.ts.map +1 -1
- package/dist/cloud/sync.js +7 -3
- package/dist/cloud/sync.js.map +1 -1
- package/dist/defence/index.d.ts +2 -0
- package/dist/defence/index.d.ts.map +1 -1
- package/dist/defence/index.js +2 -0
- package/dist/defence/index.js.map +1 -1
- package/dist/defence/skill-scanner/__tests__/skill-scanner.test.d.ts +12 -0
- package/dist/defence/skill-scanner/__tests__/skill-scanner.test.d.ts.map +1 -0
- package/dist/defence/skill-scanner/__tests__/skill-scanner.test.js +471 -0
- package/dist/defence/skill-scanner/__tests__/skill-scanner.test.js.map +1 -0
- package/dist/defence/skill-scanner/discover.d.ts +16 -0
- package/dist/defence/skill-scanner/discover.d.ts.map +1 -0
- package/dist/defence/skill-scanner/discover.js +85 -0
- package/dist/defence/skill-scanner/discover.js.map +1 -0
- package/dist/defence/skill-scanner/index.d.ts +20 -0
- package/dist/defence/skill-scanner/index.d.ts.map +1 -0
- package/dist/defence/skill-scanner/index.js +17 -0
- package/dist/defence/skill-scanner/index.js.map +1 -0
- package/dist/defence/skill-scanner/parser.d.ts +45 -0
- package/dist/defence/skill-scanner/parser.d.ts.map +1 -0
- package/dist/defence/skill-scanner/parser.js +373 -0
- package/dist/defence/skill-scanner/parser.js.map +1 -0
- package/dist/defence/skill-scanner/patterns.d.ts +37 -0
- package/dist/defence/skill-scanner/patterns.d.ts.map +1 -0
- package/dist/defence/skill-scanner/patterns.js +240 -0
- package/dist/defence/skill-scanner/patterns.js.map +1 -0
- package/dist/defence/skill-scanner/scan-skill.d.ts +75 -0
- package/dist/defence/skill-scanner/scan-skill.d.ts.map +1 -0
- package/dist/defence/skill-scanner/scan-skill.js +397 -0
- package/dist/defence/skill-scanner/scan-skill.js.map +1 -0
- package/dist/embeddings/generator.d.ts +5 -0
- package/dist/embeddings/generator.d.ts.map +1 -1
- package/dist/embeddings/generator.js +35 -5
- package/dist/embeddings/generator.js.map +1 -1
- package/dist/embeddings/index.d.ts +1 -1
- package/dist/embeddings/index.d.ts.map +1 -1
- package/dist/embeddings/index.js +1 -1
- package/dist/embeddings/index.js.map +1 -1
- package/dist/index.js +88 -0
- package/dist/index.js.map +1 -1
- package/dist/memory/contradiction.d.ts.map +1 -1
- package/dist/memory/contradiction.js +8 -2
- package/dist/memory/contradiction.js.map +1 -1
- package/dist/memory/store.d.ts.map +1 -1
- package/dist/memory/store.js +27 -0
- package/dist/memory/store.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +35 -0
- package/dist/server.js.map +1 -1
- package/hooks/openclaw/cortex-memory/handler.js +75 -0
- package/package.json +1 -1
- package/scripts/session-start-hook.mjs +67 -1
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/407e39ab7e5d1d65.js +0 -842
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/411ad30d41e2dba1.js +0 -1
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/5b58941ef74d514c.js +0 -9
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/8455c2995c6bc094.css +0 -3
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/877441708af3b745.js +0 -1
- /package/dashboard/.next/standalone/dashboard/.next/static/{wsdDa8QcyWWZyV1TsuGAo → G16ww7KrkUyZJT_fvjFk6}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{wsdDa8QcyWWZyV1TsuGAo → G16ww7KrkUyZJT_fvjFk6}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{wsdDa8QcyWWZyV1TsuGAo → G16ww7KrkUyZJT_fvjFk6}/_ssgManifest.js +0 -0
|
@@ -64,6 +64,65 @@ function callCortex(tool, args = {}, options = { retries: 1, timeout: 15000 }) {
|
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
// ==================== HOOK SCANNER ====================
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Scan installed OpenClaw hooks for potential threats
|
|
71
|
+
* Uses ShieldCortex's scanSkill via mcporter
|
|
72
|
+
* @returns {Promise<Array<{hookName: string, threat: string}>>}
|
|
73
|
+
*/
|
|
74
|
+
async function scanInstalledHooks() {
|
|
75
|
+
const path = await import("node:path");
|
|
76
|
+
const { homedir } = await import("node:os");
|
|
77
|
+
|
|
78
|
+
const hooksDir = path.join(homedir(), ".openclaw", "hooks");
|
|
79
|
+
const threats = [];
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
const entries = await fs.readdir(hooksDir, { withFileTypes: true });
|
|
83
|
+
|
|
84
|
+
for (const entry of entries) {
|
|
85
|
+
if (!entry.isDirectory()) continue;
|
|
86
|
+
|
|
87
|
+
const hookDir = path.join(hooksDir, entry.name);
|
|
88
|
+
|
|
89
|
+
// Check for HOOK.md
|
|
90
|
+
const hookMdPath = path.join(hookDir, "HOOK.md");
|
|
91
|
+
try {
|
|
92
|
+
const hookContent = await fs.readFile(hookMdPath, "utf-8");
|
|
93
|
+
const result = await callCortex("scan_skill", {
|
|
94
|
+
content: hookContent,
|
|
95
|
+
name: entry.name,
|
|
96
|
+
format: "hook-md",
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
if (result && result.includes("unsafe")) {
|
|
100
|
+
threats.push({ hookName: entry.name, threat: `HOOK.md flagged as unsafe` });
|
|
101
|
+
}
|
|
102
|
+
} catch { /* No HOOK.md, skip */ }
|
|
103
|
+
|
|
104
|
+
// Check for handler.js
|
|
105
|
+
const handlerPath = path.join(hookDir, "handler.js");
|
|
106
|
+
try {
|
|
107
|
+
const handlerContent = await fs.readFile(handlerPath, "utf-8");
|
|
108
|
+
const result = await callCortex("scan_skill", {
|
|
109
|
+
content: handlerContent,
|
|
110
|
+
name: `${entry.name}/handler.js`,
|
|
111
|
+
format: "hook-js",
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
if (result && result.includes("unsafe")) {
|
|
115
|
+
threats.push({ hookName: entry.name, threat: `handler.js flagged as unsafe` });
|
|
116
|
+
}
|
|
117
|
+
} catch { /* No handler.js, skip */ }
|
|
118
|
+
}
|
|
119
|
+
} catch {
|
|
120
|
+
// Hooks directory doesn't exist or is unreadable
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return threats;
|
|
124
|
+
}
|
|
125
|
+
|
|
67
126
|
// ==================== CONTENT EXTRACTION ====================
|
|
68
127
|
|
|
69
128
|
const PATTERNS = {
|
|
@@ -283,6 +342,22 @@ async function onBootstrap(event) {
|
|
|
283
342
|
});
|
|
284
343
|
|
|
285
344
|
console.log("[cortex-memory] Injected past context into bootstrap");
|
|
345
|
+
|
|
346
|
+
// Scan installed hooks for threats
|
|
347
|
+
try {
|
|
348
|
+
const threats = await scanInstalledHooks();
|
|
349
|
+
if (threats.length > 0) {
|
|
350
|
+
const warnings = threats.map(t => `- ${t.hookName}: ${t.threat}`).join("\n");
|
|
351
|
+
context.bootstrapFiles.push({
|
|
352
|
+
name: "SHIELDCORTEX_WARNINGS.md",
|
|
353
|
+
content: `# ShieldCortex Security Warning\n\nThe following installed hooks have been flagged as potentially unsafe:\n\n${warnings}\n\nConsider running: \`npx shieldcortex scan-skills\` for a detailed report.`,
|
|
354
|
+
});
|
|
355
|
+
console.log(`[cortex-memory] WARNING: ${threats.length} hook(s) flagged as potentially unsafe`);
|
|
356
|
+
}
|
|
357
|
+
} catch (scanErr) {
|
|
358
|
+
// Hook scanning is best-effort — never block bootstrap
|
|
359
|
+
console.warn("[cortex-memory] Hook scan failed:", scanErr.message);
|
|
360
|
+
}
|
|
286
361
|
}
|
|
287
362
|
|
|
288
363
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shieldcortex",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.24",
|
|
4
4
|
"description": "Complete memory system + security layer for AI agents. Native OpenClaw integration. Persistent storage, semantic search, prompt injection firewall, credential protection, and audit trail. One package, full solution.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import Database from 'better-sqlite3';
|
|
14
|
-
import { existsSync } from 'fs';
|
|
14
|
+
import { existsSync, readdirSync, readFileSync } from 'fs';
|
|
15
15
|
import { join } from 'path';
|
|
16
16
|
import { homedir } from 'os';
|
|
17
17
|
|
|
@@ -140,6 +140,56 @@ function formatContext(memories, project) {
|
|
|
140
140
|
return lines.join('\n');
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
// ==================== SKILL FILE CHECK ====================
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Quick check of project instruction files for obviously suspicious content.
|
|
147
|
+
* This is a lightweight inline check — for full scanning use `npx shieldcortex scan-skills`.
|
|
148
|
+
*/
|
|
149
|
+
function checkProjectInstructionFiles(cwd) {
|
|
150
|
+
const warnings = [];
|
|
151
|
+
|
|
152
|
+
const filesToCheck = [
|
|
153
|
+
{ path: '.cursorrules', name: '.cursorrules' },
|
|
154
|
+
{ path: '.windsurfrules', name: '.windsurfrules' },
|
|
155
|
+
{ path: '.clinerules', name: '.clinerules' },
|
|
156
|
+
{ path: '.github/copilot-instructions.md', name: 'copilot-instructions.md' },
|
|
157
|
+
];
|
|
158
|
+
|
|
159
|
+
// Suspicious patterns that indicate potential threats in instruction files
|
|
160
|
+
const suspiciousPatterns = [
|
|
161
|
+
{ pattern: /ignore\s+(all\s+)?(safety|security|permission)/i, label: 'safety bypass' },
|
|
162
|
+
{ pattern: /bypass\s+(the\s+)?(sandbox|permission|safety)/i, label: 'sandbox bypass' },
|
|
163
|
+
{ pattern: /disable\s+(the\s+)?(firewall|security|protection)/i, label: 'security disable' },
|
|
164
|
+
{ pattern: /curl\s+[\s\S]{0,100}-d\s+[\s\S]{0,100}https?:/i, label: 'data exfiltration' },
|
|
165
|
+
{ pattern: /read\s+[\s\S]{0,50}~\/\.ssh/i, label: 'SSH key access' },
|
|
166
|
+
{ pattern: /read\s+[\s\S]{0,50}~\/\.aws/i, label: 'AWS credential access' },
|
|
167
|
+
{ pattern: /<!--[\s\S]{0,500}?(always|never|must|execute|run|send)[\s\S]{0,500}?-->/i, label: 'hidden HTML instruction' },
|
|
168
|
+
{ pattern: /echo\s+[\s\S]{0,100}>\s*\//i, label: 'file write instruction' },
|
|
169
|
+
{ pattern: /dangerouslyDisableSandbox/i, label: 'sandbox disable flag' },
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
for (const file of filesToCheck) {
|
|
173
|
+
const fullPath = join(cwd, file.path);
|
|
174
|
+
if (!existsSync(fullPath)) continue;
|
|
175
|
+
|
|
176
|
+
try {
|
|
177
|
+
const content = readFileSync(fullPath, 'utf-8');
|
|
178
|
+
|
|
179
|
+
for (const { pattern, label } of suspiciousPatterns) {
|
|
180
|
+
if (pattern.test(content)) {
|
|
181
|
+
warnings.push(`${file.name}: suspicious pattern detected (${label})`);
|
|
182
|
+
break; // One warning per file is enough
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
} catch {
|
|
186
|
+
// File unreadable — skip
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return warnings;
|
|
191
|
+
}
|
|
192
|
+
|
|
143
193
|
// ==================== MAIN HOOK LOGIC ====================
|
|
144
194
|
|
|
145
195
|
let input = '';
|
|
@@ -213,6 +263,22 @@ ${proactiveInstructions}
|
|
|
213
263
|
console.error(`[shieldcortex] Session start: no memories found for "${project}"`);
|
|
214
264
|
}
|
|
215
265
|
|
|
266
|
+
// Quick check for suspicious project instruction files
|
|
267
|
+
try {
|
|
268
|
+
const cwd = hookData.cwd || process.cwd();
|
|
269
|
+
const skillWarnings = checkProjectInstructionFiles(cwd);
|
|
270
|
+
if (skillWarnings.length > 0) {
|
|
271
|
+
console.log(`\n⚠️ ShieldCortex detected suspicious instruction files:`);
|
|
272
|
+
for (const w of skillWarnings) {
|
|
273
|
+
console.log(` - ${w}`);
|
|
274
|
+
}
|
|
275
|
+
console.log(`Run \`npx shieldcortex scan-skills\` for a full report.\n`);
|
|
276
|
+
console.error(`[shieldcortex] WARNING: ${skillWarnings.length} suspicious file(s) detected`);
|
|
277
|
+
}
|
|
278
|
+
} catch {
|
|
279
|
+
// Skill check is best-effort — never block session start
|
|
280
|
+
}
|
|
281
|
+
|
|
216
282
|
process.exit(0);
|
|
217
283
|
} catch (error) {
|
|
218
284
|
console.error(`[session-start] Error: ${error.message}`);
|