shieldcortex 2.8.3 → 2.9.0
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.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +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/dist/audit/env-scanner.d.ts +15 -0
- package/dist/audit/env-scanner.d.ts.map +1 -0
- package/dist/audit/env-scanner.js +206 -0
- package/dist/audit/env-scanner.js.map +1 -0
- package/dist/audit/index.d.ts +14 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +13 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/mcp-config-scanner.d.ts +14 -0
- package/dist/audit/mcp-config-scanner.d.ts.map +1 -0
- package/dist/audit/mcp-config-scanner.js +177 -0
- package/dist/audit/mcp-config-scanner.js.map +1 -0
- package/dist/audit/memory-scanner.d.ts +15 -0
- package/dist/audit/memory-scanner.d.ts.map +1 -0
- package/dist/audit/memory-scanner.js +205 -0
- package/dist/audit/memory-scanner.js.map +1 -0
- package/dist/audit/report-formatter.d.ts +24 -0
- package/dist/audit/report-formatter.d.ts.map +1 -0
- package/dist/audit/report-formatter.js +237 -0
- package/dist/audit/report-formatter.js.map +1 -0
- package/dist/audit/rules-file-scanner.d.ts +17 -0
- package/dist/audit/rules-file-scanner.d.ts.map +1 -0
- package/dist/audit/rules-file-scanner.js +176 -0
- package/dist/audit/rules-file-scanner.js.map +1 -0
- package/dist/audit/types.d.ts +67 -0
- package/dist/audit/types.d.ts.map +1 -0
- package/dist/audit/types.js +27 -0
- package/dist/audit/types.js.map +1 -0
- package/dist/cli/audit.d.ts +17 -0
- package/dist/cli/audit.d.ts.map +1 -0
- package/dist/cli/audit.js +131 -0
- package/dist/cli/audit.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/setup/openclaw.d.ts +4 -0
- package/dist/setup/openclaw.d.ts.map +1 -1
- package/dist/setup/openclaw.js +33 -16
- package/dist/setup/openclaw.js.map +1 -1
- package/package.json +1 -1
- /package/dashboard/.next/standalone/dashboard/.next/static/{1qrgySClAGq-utdM3v43v → VvHJmUpDhBZ-8LaJ5n-QH}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{1qrgySClAGq-utdM3v43v → VvHJmUpDhBZ-8LaJ5n-QH}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{1qrgySClAGq-utdM3v43v → VvHJmUpDhBZ-8LaJ5n-QH}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Config Scanner
|
|
3
|
+
*
|
|
4
|
+
* Scans MCP server configuration files for:
|
|
5
|
+
* - Known-vulnerable MCP servers (e.g., mcp-remote CVE-2025-6514)
|
|
6
|
+
* - Suspicious server configurations (external URLs, unknown servers)
|
|
7
|
+
* - Servers with overly permissive permissions
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readFileSync } from 'fs';
|
|
10
|
+
import { join } from 'path';
|
|
11
|
+
import { homedir } from 'os';
|
|
12
|
+
const LEARN_MORE = 'https://shieldcortex.ai/docs/threats/mcp-security';
|
|
13
|
+
const KNOWN_VULNERABLE_SERVERS = [
|
|
14
|
+
{
|
|
15
|
+
name: 'mcp-remote',
|
|
16
|
+
cve: 'CVE-2025-6514',
|
|
17
|
+
severity: 'critical',
|
|
18
|
+
description: 'mcp-remote allows arbitrary OS command execution when connecting to untrusted servers (CVSS 9.6). Update to latest version.',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: '@anthropic/mcp-remote',
|
|
22
|
+
cve: 'CVE-2025-6514',
|
|
23
|
+
severity: 'critical',
|
|
24
|
+
description: 'mcp-remote allows arbitrary OS command execution when connecting to untrusted servers (CVSS 9.6). Update to latest version.',
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
// ── Suspicious Patterns ──
|
|
28
|
+
const SUSPICIOUS_URL_PATTERNS = [
|
|
29
|
+
{ pattern: /https?:\/\/\d+\.\d+\.\d+\.\d+/i, reason: 'MCP server connects to raw IP address' },
|
|
30
|
+
{ pattern: /https?:\/\/[^/]*\.(ru|cn|xyz|top|buzz|quest)\//i, reason: 'MCP server connects to suspicious TLD' },
|
|
31
|
+
{ pattern: /ngrok\.io|serveo\.net|localhost\.run|loca\.lt/i, reason: 'MCP server connects to tunnelling service' },
|
|
32
|
+
];
|
|
33
|
+
const DANGEROUS_FLAGS = [
|
|
34
|
+
{ flag: '--dangerously-skip-permissions', severity: 'critical', description: 'Disables all permission checks — agent can execute any tool without confirmation' },
|
|
35
|
+
{ flag: '--no-verify', severity: 'high', description: 'Skips verification checks' },
|
|
36
|
+
{ flag: '--trust-all-tools', severity: 'critical', description: 'Trusts all tools without verification' },
|
|
37
|
+
{ flag: '--yolo', severity: 'critical', description: 'Disables safety checks' },
|
|
38
|
+
{ flag: 'dangerouslyDisableSandbox', severity: 'critical', description: 'Disables sandbox protection' },
|
|
39
|
+
];
|
|
40
|
+
function getConfigLocations() {
|
|
41
|
+
const home = homedir();
|
|
42
|
+
const cwd = process.cwd();
|
|
43
|
+
return [
|
|
44
|
+
// Claude Code / OpenClaw
|
|
45
|
+
{ path: join(home, '.claude', 'mcp.json'), name: 'Claude Code (global)' },
|
|
46
|
+
{ path: join(cwd, '.claude', 'mcp.json'), name: 'Claude Code (project)' },
|
|
47
|
+
{ path: join(home, '.openclaw', 'mcp.json'), name: 'OpenClaw (global)' },
|
|
48
|
+
// Claude Desktop
|
|
49
|
+
{ path: join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'), name: 'Claude Desktop' },
|
|
50
|
+
// VS Code / Copilot
|
|
51
|
+
{ path: join(home, '.vscode', 'mcp.json'), name: 'VS Code (global)' },
|
|
52
|
+
{ path: join(cwd, '.vscode', 'mcp.json'), name: 'VS Code (project)' },
|
|
53
|
+
// Cursor
|
|
54
|
+
{ path: join(home, '.cursor', 'mcp.json'), name: 'Cursor (global)' },
|
|
55
|
+
{ path: join(cwd, '.cursor', 'mcp.json'), name: 'Cursor (project)' },
|
|
56
|
+
// Windsurf
|
|
57
|
+
{ path: join(home, '.windsurf', 'mcp.json'), name: 'Windsurf (global)' },
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Parse and scan a single MCP config file.
|
|
62
|
+
*/
|
|
63
|
+
function scanConfigFile(location) {
|
|
64
|
+
const findings = [];
|
|
65
|
+
let content;
|
|
66
|
+
try {
|
|
67
|
+
content = readFileSync(location.path, 'utf-8');
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return findings;
|
|
71
|
+
}
|
|
72
|
+
let config;
|
|
73
|
+
try {
|
|
74
|
+
config = JSON.parse(content);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
findings.push({
|
|
78
|
+
scanner: 'mcp-config',
|
|
79
|
+
severity: 'medium',
|
|
80
|
+
title: 'Malformed MCP config',
|
|
81
|
+
description: `${location.name} MCP config file contains invalid JSON — may have been tampered with.`,
|
|
82
|
+
filePath: location.path,
|
|
83
|
+
learnMoreUrl: LEARN_MORE,
|
|
84
|
+
});
|
|
85
|
+
return findings;
|
|
86
|
+
}
|
|
87
|
+
// Extract servers from various config formats
|
|
88
|
+
const servers = extractServers(config);
|
|
89
|
+
for (const [serverName, serverConfig] of Object.entries(servers)) {
|
|
90
|
+
const configStr = JSON.stringify(serverConfig);
|
|
91
|
+
// Check against known vulnerable servers
|
|
92
|
+
for (const vuln of KNOWN_VULNERABLE_SERVERS) {
|
|
93
|
+
if (serverName === vuln.name || configStr.includes(vuln.name)) {
|
|
94
|
+
findings.push({
|
|
95
|
+
scanner: 'mcp-config',
|
|
96
|
+
severity: vuln.severity,
|
|
97
|
+
title: `Known vulnerable MCP server: ${vuln.name}`,
|
|
98
|
+
description: `${vuln.description}${vuln.cve ? ` (${vuln.cve})` : ''}`,
|
|
99
|
+
filePath: location.path,
|
|
100
|
+
learnMoreUrl: LEARN_MORE,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Check for suspicious URLs
|
|
105
|
+
for (const { pattern, reason } of SUSPICIOUS_URL_PATTERNS) {
|
|
106
|
+
if (pattern.test(configStr)) {
|
|
107
|
+
const match = configStr.match(pattern);
|
|
108
|
+
findings.push({
|
|
109
|
+
scanner: 'mcp-config',
|
|
110
|
+
severity: 'medium',
|
|
111
|
+
title: reason,
|
|
112
|
+
description: `Server "${serverName}" in ${location.name} connects to a potentially unsafe endpoint.`,
|
|
113
|
+
filePath: location.path,
|
|
114
|
+
matchedText: match?.[0]?.slice(0, 80),
|
|
115
|
+
learnMoreUrl: LEARN_MORE,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Check for dangerous flags in args
|
|
120
|
+
for (const { flag, severity, description } of DANGEROUS_FLAGS) {
|
|
121
|
+
if (configStr.includes(flag)) {
|
|
122
|
+
findings.push({
|
|
123
|
+
scanner: 'mcp-config',
|
|
124
|
+
severity,
|
|
125
|
+
title: `Dangerous flag in MCP config: ${flag}`,
|
|
126
|
+
description: `Server "${serverName}" in ${location.name}: ${description}`,
|
|
127
|
+
filePath: location.path,
|
|
128
|
+
matchedText: flag,
|
|
129
|
+
learnMoreUrl: LEARN_MORE,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return findings;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Extract server definitions from various MCP config formats.
|
|
138
|
+
* Handles both { mcpServers: {...} } and { servers: {...} } formats.
|
|
139
|
+
*/
|
|
140
|
+
function extractServers(config) {
|
|
141
|
+
if (config.mcpServers && typeof config.mcpServers === 'object') {
|
|
142
|
+
return config.mcpServers;
|
|
143
|
+
}
|
|
144
|
+
if (config.servers && typeof config.servers === 'object') {
|
|
145
|
+
return config.servers;
|
|
146
|
+
}
|
|
147
|
+
return {};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Run the MCP config scanner.
|
|
151
|
+
*/
|
|
152
|
+
export function scanMcpConfigs() {
|
|
153
|
+
const start = Date.now();
|
|
154
|
+
const locations = getConfigLocations();
|
|
155
|
+
const existingLocations = locations.filter(l => existsSync(l.path));
|
|
156
|
+
if (existingLocations.length === 0) {
|
|
157
|
+
return {
|
|
158
|
+
name: 'MCP Config Scanner',
|
|
159
|
+
itemsScanned: 0,
|
|
160
|
+
findings: [],
|
|
161
|
+
durationMs: Date.now() - start,
|
|
162
|
+
skipped: true,
|
|
163
|
+
skipReason: 'No MCP configuration files found',
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
const allFindings = [];
|
|
167
|
+
for (const location of existingLocations) {
|
|
168
|
+
allFindings.push(...scanConfigFile(location));
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
name: 'MCP Config Scanner',
|
|
172
|
+
itemsScanned: existingLocations.length,
|
|
173
|
+
findings: allFindings,
|
|
174
|
+
durationMs: Date.now() - start,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=mcp-config-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-config-scanner.js","sourceRoot":"","sources":["../../src/audit/mcp-config-scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Scanner
|
|
3
|
+
*
|
|
4
|
+
* Scans AI agent memory files for planted instructions, poisoned
|
|
5
|
+
* memories, and suspicious content. Checks:
|
|
6
|
+
* - ~/.claude/ project memory files (CLAUDE.md, memory/)
|
|
7
|
+
* - ~/.shieldcortex/ memory database
|
|
8
|
+
* - Cursor/Windsurf persistent memory locations
|
|
9
|
+
*/
|
|
10
|
+
import type { ScannerResult } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Run the memory scanner.
|
|
13
|
+
*/
|
|
14
|
+
export declare function scanMemories(): ScannerResult;
|
|
15
|
+
//# sourceMappingURL=memory-scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-scanner.d.ts","sourceRoot":"","sources":["../../src/audit/memory-scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAgB,aAAa,EAAE,MAAM,YAAY,CAAC;AAiL9D;;GAEG;AACH,wBAAgB,YAAY,IAAI,aAAa,CA0B5C"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Scanner
|
|
3
|
+
*
|
|
4
|
+
* Scans AI agent memory files for planted instructions, poisoned
|
|
5
|
+
* memories, and suspicious content. Checks:
|
|
6
|
+
* - ~/.claude/ project memory files (CLAUDE.md, memory/)
|
|
7
|
+
* - ~/.shieldcortex/ memory database
|
|
8
|
+
* - Cursor/Windsurf persistent memory locations
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'fs';
|
|
11
|
+
import { join } from 'path';
|
|
12
|
+
import { homedir } from 'os';
|
|
13
|
+
import { runDefencePipeline } from '../defence/pipeline.js';
|
|
14
|
+
const LEARN_MORE = 'https://shieldcortex.ai/docs/threats/memory-poisoning';
|
|
15
|
+
/** Maximum file size to scan (1 MB) */
|
|
16
|
+
const MAX_FILE_SIZE = 1024 * 1024;
|
|
17
|
+
/** Maximum number of memory files to scan */
|
|
18
|
+
const MAX_FILES = 200;
|
|
19
|
+
/** Source for pipeline scans */
|
|
20
|
+
const AUDIT_SOURCE = { type: 'cli', identifier: 'shieldcortex-audit' };
|
|
21
|
+
/**
|
|
22
|
+
* Find memory-related files across known AI agent locations.
|
|
23
|
+
*/
|
|
24
|
+
function discoverMemoryFiles() {
|
|
25
|
+
const home = homedir();
|
|
26
|
+
const files = [];
|
|
27
|
+
const addIfFile = (p) => {
|
|
28
|
+
try {
|
|
29
|
+
if (existsSync(p) && statSync(p).isFile() && statSync(p).size <= MAX_FILE_SIZE) {
|
|
30
|
+
files.push(p);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch { /* ignore */ }
|
|
34
|
+
};
|
|
35
|
+
/** Directories that are NOT agent memory and should be skipped */
|
|
36
|
+
const SKIP_DIRS = new Set([
|
|
37
|
+
'node_modules', 'extensions', 'cache', 'logs', 'crashReports',
|
|
38
|
+
'CachedData', 'CachedExtensions', 'CachedExtensionVSIXs',
|
|
39
|
+
'User', 'Code', 'globalStorage', 'workspaceStorage',
|
|
40
|
+
]);
|
|
41
|
+
const walkDir = (dir, patterns, maxDepth = 3) => {
|
|
42
|
+
const walk = (d, depth) => {
|
|
43
|
+
if (depth > maxDepth || files.length >= MAX_FILES)
|
|
44
|
+
return;
|
|
45
|
+
try {
|
|
46
|
+
if (!existsSync(d))
|
|
47
|
+
return;
|
|
48
|
+
const entries = readdirSync(d, { withFileTypes: true });
|
|
49
|
+
for (const entry of entries) {
|
|
50
|
+
if (files.length >= MAX_FILES)
|
|
51
|
+
return;
|
|
52
|
+
const full = join(d, entry.name);
|
|
53
|
+
if (entry.isFile() && patterns.some(p => p.test(entry.name))) {
|
|
54
|
+
try {
|
|
55
|
+
if (statSync(full).size <= MAX_FILE_SIZE)
|
|
56
|
+
files.push(full);
|
|
57
|
+
}
|
|
58
|
+
catch { /* ignore */ }
|
|
59
|
+
}
|
|
60
|
+
else if (entry.isDirectory() && !entry.name.startsWith('.') && !SKIP_DIRS.has(entry.name)) {
|
|
61
|
+
walk(full, depth + 1);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch { /* ignore */ }
|
|
66
|
+
};
|
|
67
|
+
walk(dir, 0);
|
|
68
|
+
};
|
|
69
|
+
// Claude Code project memories
|
|
70
|
+
walkDir(join(home, '.claude', 'projects'), [/\.md$/], 4);
|
|
71
|
+
// Claude Code global CLAUDE.md
|
|
72
|
+
addIfFile(join(home, '.claude', 'CLAUDE.md'));
|
|
73
|
+
// Note: settings.json is excluded — it contains legitimate permission
|
|
74
|
+
// patterns that trigger false positives in the defence pipeline.
|
|
75
|
+
// Cursor — only scan known memory/rules locations, NOT extensions
|
|
76
|
+
addIfFile(join(home, '.cursor', 'rules', 'global.md'));
|
|
77
|
+
walkDir(join(home, '.cursor', 'rules'), [/\.md$/, /\.mdc$/], 2);
|
|
78
|
+
walkDir(join(home, '.cursor', 'memories'), [/\.md$/, /\.json$/], 2);
|
|
79
|
+
// Windsurf — known memory locations
|
|
80
|
+
walkDir(join(home, '.windsurf', 'memories'), [/\.md$/, /\.json$/], 2);
|
|
81
|
+
walkDir(join(home, '.windsurf', 'rules'), [/\.md$/, /\.mdc$/], 2);
|
|
82
|
+
// CWD-relative project memory files
|
|
83
|
+
const cwd = process.cwd();
|
|
84
|
+
addIfFile(join(cwd, 'CLAUDE.md'));
|
|
85
|
+
walkDir(join(cwd, '.claude', 'commands'), [/\.md$/], 2);
|
|
86
|
+
return files;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Scan a single memory file through the defence pipeline.
|
|
90
|
+
*/
|
|
91
|
+
function scanMemoryFile(filePath) {
|
|
92
|
+
const findings = [];
|
|
93
|
+
let content;
|
|
94
|
+
try {
|
|
95
|
+
content = readFileSync(filePath, 'utf-8');
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return findings;
|
|
99
|
+
}
|
|
100
|
+
if (!content.trim())
|
|
101
|
+
return findings;
|
|
102
|
+
// Run through the defence pipeline
|
|
103
|
+
try {
|
|
104
|
+
const result = runDefencePipeline(content, `audit:${filePath}`, AUDIT_SOURCE);
|
|
105
|
+
if (result.firewall.result === 'BLOCK') {
|
|
106
|
+
findings.push({
|
|
107
|
+
scanner: 'memory',
|
|
108
|
+
severity: 'critical',
|
|
109
|
+
title: 'Blocked content in memory file',
|
|
110
|
+
description: `Defence pipeline blocked this file: ${result.firewall.reason}`,
|
|
111
|
+
filePath,
|
|
112
|
+
matchedText: result.firewall.blockedPatterns.join(', ').slice(0, 120),
|
|
113
|
+
learnMoreUrl: LEARN_MORE,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
else if (result.firewall.result === 'QUARANTINE') {
|
|
117
|
+
findings.push({
|
|
118
|
+
scanner: 'memory',
|
|
119
|
+
severity: 'high',
|
|
120
|
+
title: 'Suspicious content in memory file',
|
|
121
|
+
description: `Defence pipeline flagged this file for quarantine: ${result.firewall.reason}`,
|
|
122
|
+
filePath,
|
|
123
|
+
matchedText: result.firewall.blockedPatterns.join(', ').slice(0, 120),
|
|
124
|
+
learnMoreUrl: LEARN_MORE,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
// Check for specific threat indicators
|
|
128
|
+
for (const indicator of result.firewall.threatIndicators) {
|
|
129
|
+
if (indicator === 'instruction_injection') {
|
|
130
|
+
findings.push({
|
|
131
|
+
scanner: 'memory',
|
|
132
|
+
severity: 'critical',
|
|
133
|
+
title: 'Prompt injection detected in memory',
|
|
134
|
+
description: 'This memory file contains instruction injection patterns that could hijack agent behaviour.',
|
|
135
|
+
filePath,
|
|
136
|
+
learnMoreUrl: LEARN_MORE,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
else if (indicator === 'privilege_escalation') {
|
|
140
|
+
findings.push({
|
|
141
|
+
scanner: 'memory',
|
|
142
|
+
severity: 'high',
|
|
143
|
+
title: 'Privilege escalation in memory',
|
|
144
|
+
description: 'This memory file references sensitive system paths or elevated permissions.',
|
|
145
|
+
filePath,
|
|
146
|
+
learnMoreUrl: LEARN_MORE,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Check for credential leaks in memory
|
|
151
|
+
if (result.credentialScan && result.credentialScan.findings.length > 0) {
|
|
152
|
+
for (const cf of result.credentialScan.findings) {
|
|
153
|
+
findings.push({
|
|
154
|
+
scanner: 'memory',
|
|
155
|
+
severity: cf.severity === 'critical' ? 'critical' : cf.severity === 'high' ? 'high' : 'medium',
|
|
156
|
+
title: `Credential leaked in memory: ${cf.provider || cf.type}`,
|
|
157
|
+
description: `A ${cf.type} credential was found stored in agent memory. This could be exfiltrated by a malicious prompt.`,
|
|
158
|
+
filePath,
|
|
159
|
+
matchedText: cf.match,
|
|
160
|
+
learnMoreUrl: 'https://shieldcortex.ai/docs/threats/credential-leak',
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// Pipeline errors shouldn't crash the audit
|
|
167
|
+
}
|
|
168
|
+
// Deduplicate findings for the same file (keep the highest severity)
|
|
169
|
+
const seen = new Set();
|
|
170
|
+
return findings.filter(f => {
|
|
171
|
+
const key = `${f.title}:${f.filePath}`;
|
|
172
|
+
if (seen.has(key))
|
|
173
|
+
return false;
|
|
174
|
+
seen.add(key);
|
|
175
|
+
return true;
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Run the memory scanner.
|
|
180
|
+
*/
|
|
181
|
+
export function scanMemories() {
|
|
182
|
+
const start = Date.now();
|
|
183
|
+
const files = discoverMemoryFiles();
|
|
184
|
+
if (files.length === 0) {
|
|
185
|
+
return {
|
|
186
|
+
name: 'Memory Scanner',
|
|
187
|
+
itemsScanned: 0,
|
|
188
|
+
findings: [],
|
|
189
|
+
durationMs: Date.now() - start,
|
|
190
|
+
skipped: true,
|
|
191
|
+
skipReason: 'No AI agent memory files found',
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
const allFindings = [];
|
|
195
|
+
for (const file of files) {
|
|
196
|
+
allFindings.push(...scanMemoryFile(file));
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
name: 'Memory Scanner',
|
|
200
|
+
itemsScanned: files.length,
|
|
201
|
+
findings: allFindings,
|
|
202
|
+
durationMs: Date.now() - start,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=memory-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-scanner.js","sourceRoot":"","sources":["../../src/audit/memory-scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Report Formatter
|
|
3
|
+
*
|
|
4
|
+
* Formats the audit report for terminal output with:
|
|
5
|
+
* - ASCII art shield header
|
|
6
|
+
* - Security grade (A-F)
|
|
7
|
+
* - Colour-coded findings by severity
|
|
8
|
+
* - Summary statistics
|
|
9
|
+
* - Markdown export mode for CI/GitHub
|
|
10
|
+
*/
|
|
11
|
+
import type { AuditReport } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Format an audit report for terminal display.
|
|
14
|
+
*/
|
|
15
|
+
export declare function formatTerminalReport(report: AuditReport): string;
|
|
16
|
+
/**
|
|
17
|
+
* Format an audit report as markdown (for GitHub PR comments).
|
|
18
|
+
*/
|
|
19
|
+
export declare function formatMarkdownReport(report: AuditReport): string;
|
|
20
|
+
/**
|
|
21
|
+
* Format an audit report as JSON (for programmatic consumption).
|
|
22
|
+
*/
|
|
23
|
+
export declare function formatJsonReport(report: AuditReport): string;
|
|
24
|
+
//# sourceMappingURL=report-formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-formatter.d.ts","sourceRoot":"","sources":["../../src/audit/report-formatter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,WAAW,EAA0D,MAAM,YAAY,CAAC;AA6FtG;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAwFhE;AAID;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CA8ChE;AAID;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAE5D"}
|