project-shield 1.0.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.
Files changed (71) hide show
  1. package/README.md +440 -0
  2. package/dist/index.d.ts +3 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +151 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/integrity/failsafe.d.ts +17 -0
  7. package/dist/integrity/failsafe.d.ts.map +1 -0
  8. package/dist/integrity/failsafe.js +45 -0
  9. package/dist/integrity/failsafe.js.map +1 -0
  10. package/dist/integrity/ruleset.d.ts +12 -0
  11. package/dist/integrity/ruleset.d.ts.map +1 -0
  12. package/dist/integrity/ruleset.js +77 -0
  13. package/dist/integrity/ruleset.js.map +1 -0
  14. package/dist/integrity/seal.d.ts +12 -0
  15. package/dist/integrity/seal.d.ts.map +1 -0
  16. package/dist/integrity/seal.js +77 -0
  17. package/dist/integrity/seal.js.map +1 -0
  18. package/dist/output/badge.d.ts +16 -0
  19. package/dist/output/badge.d.ts.map +1 -0
  20. package/dist/output/badge.js +112 -0
  21. package/dist/output/badge.js.map +1 -0
  22. package/dist/output/evidence.d.ts +18 -0
  23. package/dist/output/evidence.d.ts.map +1 -0
  24. package/dist/output/evidence.js +205 -0
  25. package/dist/output/evidence.js.map +1 -0
  26. package/dist/output/fixit.d.ts +32 -0
  27. package/dist/output/fixit.d.ts.map +1 -0
  28. package/dist/output/fixit.js +387 -0
  29. package/dist/output/fixit.js.map +1 -0
  30. package/dist/output/terminal.d.ts +10 -0
  31. package/dist/output/terminal.d.ts.map +1 -0
  32. package/dist/output/terminal.js +190 -0
  33. package/dist/output/terminal.js.map +1 -0
  34. package/dist/scanner/engine.d.ts +6 -0
  35. package/dist/scanner/engine.d.ts.map +1 -0
  36. package/dist/scanner/engine.js +155 -0
  37. package/dist/scanner/engine.js.map +1 -0
  38. package/dist/scanner/ignore.d.ts +20 -0
  39. package/dist/scanner/ignore.d.ts.map +1 -0
  40. package/dist/scanner/ignore.js +125 -0
  41. package/dist/scanner/ignore.js.map +1 -0
  42. package/dist/scanner/injection.d.ts +15 -0
  43. package/dist/scanner/injection.d.ts.map +1 -0
  44. package/dist/scanner/injection.js +234 -0
  45. package/dist/scanner/injection.js.map +1 -0
  46. package/dist/scanner/mcp.d.ts +6 -0
  47. package/dist/scanner/mcp.d.ts.map +1 -0
  48. package/dist/scanner/mcp.js +322 -0
  49. package/dist/scanner/mcp.js.map +1 -0
  50. package/dist/scanner/pii.d.ts +21 -0
  51. package/dist/scanner/pii.d.ts.map +1 -0
  52. package/dist/scanner/pii.js +161 -0
  53. package/dist/scanner/pii.js.map +1 -0
  54. package/dist/scanner/secrets.d.ts +10 -0
  55. package/dist/scanner/secrets.d.ts.map +1 -0
  56. package/dist/scanner/secrets.js +224 -0
  57. package/dist/scanner/secrets.js.map +1 -0
  58. package/dist/scoring/lock.d.ts +12 -0
  59. package/dist/scoring/lock.d.ts.map +1 -0
  60. package/dist/scoring/lock.js +58 -0
  61. package/dist/scoring/lock.js.map +1 -0
  62. package/dist/scoring/score.d.ts +14 -0
  63. package/dist/scoring/score.d.ts.map +1 -0
  64. package/dist/scoring/score.js +74 -0
  65. package/dist/scoring/score.js.map +1 -0
  66. package/dist/types/index.d.ts +205 -0
  67. package/dist/types/index.d.ts.map +1 -0
  68. package/dist/types/index.js +3 -0
  69. package/dist/types/index.js.map +1 -0
  70. package/package.json +52 -0
  71. package/rules/v1.0.0.json +248 -0
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.scan = scan;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const glob_1 = require("glob");
40
+ const ruleset_js_1 = require("../integrity/ruleset.js");
41
+ const failsafe_js_1 = require("../integrity/failsafe.js");
42
+ const ignore_js_1 = require("./ignore.js");
43
+ const secrets_js_1 = require("./secrets.js");
44
+ const pii_js_1 = require("./pii.js");
45
+ const mcp_js_1 = require("./mcp.js");
46
+ const injection_js_1 = require("./injection.js");
47
+ // Binary file extensions to skip
48
+ const BINARY_EXTENSIONS = new Set([
49
+ '.png', '.jpg', '.jpeg', '.gif', '.bmp', '.ico', '.svg',
50
+ '.woff', '.woff2', '.ttf', '.eot', '.otf',
51
+ '.zip', '.tar', '.gz', '.bz2', '.7z', '.rar',
52
+ '.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx',
53
+ '.exe', '.dll', '.so', '.dylib', '.bin',
54
+ '.mp3', '.mp4', '.avi', '.mov', '.wav', '.flac',
55
+ '.pyc', '.class', '.o', '.obj',
56
+ '.lock',
57
+ ]);
58
+ // Default directories to always exclude
59
+ const DEFAULT_EXCLUDE_DIRS = [
60
+ 'node_modules',
61
+ '.git',
62
+ 'dist',
63
+ 'build',
64
+ '.next',
65
+ '__pycache__',
66
+ '.venv',
67
+ 'venv',
68
+ 'coverage',
69
+ ];
70
+ /**
71
+ * Check if a file is binary by extension.
72
+ */
73
+ function isBinaryFile(filePath) {
74
+ const ext = path.extname(filePath).toLowerCase();
75
+ return BINARY_EXTENSIONS.has(ext);
76
+ }
77
+ /**
78
+ * Run the full scan pipeline.
79
+ */
80
+ async function scan(config) {
81
+ return (0, failsafe_js_1.withFailsafe)(async () => {
82
+ const startTime = Date.now();
83
+ // Load ruleset
84
+ const ruleset = (0, ruleset_js_1.loadRuleset)(config.rulesetPath);
85
+ // Load ignore patterns
86
+ const ignorePatterns = (0, ignore_js_1.loadIgnorePatterns)(config.targetPath, config.ignorePath);
87
+ // Find all files
88
+ const allFiles = await (0, glob_1.glob)('**/*', {
89
+ cwd: config.targetPath,
90
+ nodir: true,
91
+ dot: true,
92
+ ignore: DEFAULT_EXCLUDE_DIRS.map(d => `${d}/**`),
93
+ absolute: false,
94
+ });
95
+ let filesExcluded = 0;
96
+ const filesToScan = [];
97
+ for (const file of allFiles) {
98
+ // Skip binary files
99
+ if (isBinaryFile(file)) {
100
+ filesExcluded++;
101
+ continue;
102
+ }
103
+ // Skip ignored files
104
+ if ((0, ignore_js_1.isFileIgnored)(file, ignorePatterns)) {
105
+ filesExcluded++;
106
+ continue;
107
+ }
108
+ filesToScan.push(file);
109
+ }
110
+ // Scan each file
111
+ const allSecrets = [];
112
+ const allPII = [];
113
+ const allInjection = [];
114
+ for (const file of filesToScan) {
115
+ const fullFilePath = path.join(config.targetPath, file);
116
+ let content;
117
+ try {
118
+ content = fs.readFileSync(fullFilePath, 'utf-8');
119
+ }
120
+ catch {
121
+ // Skip files that can't be read
122
+ continue;
123
+ }
124
+ const secrets = (0, secrets_js_1.scanFileSecrets)(content, file, ruleset);
125
+ const pii = (0, pii_js_1.scanFilePII)(content, file, ruleset);
126
+ const injection = (0, injection_js_1.scanFileInjection)(content, file, ruleset);
127
+ allSecrets.push(...secrets);
128
+ allPII.push(...pii);
129
+ allInjection.push(...injection);
130
+ }
131
+ // MCP scan (after secrets, to cross-reference)
132
+ const allMCP = await (0, mcp_js_1.scanMCPConfigs)(config.targetPath, ruleset, allSecrets);
133
+ const timeMs = Date.now() - startTime;
134
+ return {
135
+ secrets: allSecrets,
136
+ pii: allPII,
137
+ mcp: allMCP,
138
+ injection: allInjection,
139
+ summary: {
140
+ filesScanned: filesToScan.length,
141
+ filesExcluded,
142
+ timeMs,
143
+ critical: allSecrets.filter(s => s.severity === 'critical').length,
144
+ warning: allSecrets.filter(s => s.severity === 'warning').length,
145
+ confirmedPii: allPII.filter(p => p.severity === 'confirmed').length,
146
+ possiblePii: allPII.filter(p => p.severity === 'possible').length,
147
+ mcpCritical: allMCP.filter(m => m.overallSeverity === 'critical').length,
148
+ mcpWarning: allMCP.filter(m => m.overallSeverity === 'warning').length,
149
+ injectionCritical: allInjection.filter(j => j.severity === 'critical').length,
150
+ injectionWarning: allInjection.filter(j => j.severity === 'warning').length,
151
+ },
152
+ };
153
+ });
154
+ }
155
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/scanner/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Check if a line has a shield-ignore comment.
3
+ * Supports: // shield-ignore, # shield-ignore, /* shield-ignore *​/
4
+ */
5
+ export declare function isLineIgnored(line: string): boolean;
6
+ /**
7
+ * Parse a .shieldignore file (same format as .gitignore).
8
+ * Returns an array of glob patterns to exclude.
9
+ */
10
+ export declare function parseShieldIgnore(ignorePath: string): string[];
11
+ /**
12
+ * Check if a file path matches any of the ignore patterns.
13
+ * Uses simple glob matching (supports * and ** patterns).
14
+ */
15
+ export declare function isFileIgnored(filePath: string, patterns: string[]): boolean;
16
+ /**
17
+ * Load ignore patterns from a .shieldignore file, resolving relative to a base directory.
18
+ */
19
+ export declare function loadIgnorePatterns(basePath: string, customIgnorePath?: string): string[];
20
+ //# sourceMappingURL=ignore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ignore.d.ts","sourceRoot":"","sources":["../../src/scanner/ignore.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQnD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAU9D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAmB3E;AA0BD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAaxF"}
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.isLineIgnored = isLineIgnored;
37
+ exports.parseShieldIgnore = parseShieldIgnore;
38
+ exports.isFileIgnored = isFileIgnored;
39
+ exports.loadIgnorePatterns = loadIgnorePatterns;
40
+ const fs = __importStar(require("node:fs"));
41
+ const path = __importStar(require("node:path"));
42
+ /**
43
+ * Check if a line has a shield-ignore comment.
44
+ * Supports: // shield-ignore, # shield-ignore, /* shield-ignore *​/
45
+ */
46
+ function isLineIgnored(line) {
47
+ const trimmed = line.trim();
48
+ // Check for inline comments
49
+ return (trimmed.includes('// shield-ignore') ||
50
+ trimmed.includes('# shield-ignore') ||
51
+ trimmed.includes('/* shield-ignore'));
52
+ }
53
+ /**
54
+ * Parse a .shieldignore file (same format as .gitignore).
55
+ * Returns an array of glob patterns to exclude.
56
+ */
57
+ function parseShieldIgnore(ignorePath) {
58
+ if (!fs.existsSync(ignorePath)) {
59
+ return [];
60
+ }
61
+ const content = fs.readFileSync(ignorePath, 'utf-8');
62
+ return content
63
+ .split('\n')
64
+ .map(line => line.trim())
65
+ .filter(line => line.length > 0 && !line.startsWith('#'));
66
+ }
67
+ /**
68
+ * Check if a file path matches any of the ignore patterns.
69
+ * Uses simple glob matching (supports * and ** patterns).
70
+ */
71
+ function isFileIgnored(filePath, patterns) {
72
+ const normalized = filePath.replace(/\\/g, '/');
73
+ for (const pattern of patterns) {
74
+ const normalizedPattern = pattern.replace(/\\/g, '/');
75
+ // Direct match
76
+ if (normalized === normalizedPattern)
77
+ return true;
78
+ // Check if the file is inside an ignored directory
79
+ if (normalizedPattern.endsWith('/')) {
80
+ if (normalized.startsWith(normalizedPattern))
81
+ return true;
82
+ }
83
+ // Simple wildcard matching
84
+ if (matchGlob(normalized, normalizedPattern))
85
+ return true;
86
+ }
87
+ return false;
88
+ }
89
+ /**
90
+ * Simple glob matcher supporting * and ** patterns.
91
+ * ** matches zero or more directories.
92
+ */
93
+ function matchGlob(filePath, pattern) {
94
+ // Handle **/ specifically: it should match zero or more directories
95
+ // Replace **/ with a special token first
96
+ let regexStr = pattern
97
+ .replace(/[.+^${}()|[\]\\]/g, '\\$&')
98
+ .replace(/\*\*\//g, '{{GLOBSTAR_SLASH}}')
99
+ .replace(/\*\*/g, '{{GLOBSTAR}}')
100
+ .replace(/\*/g, '[^/]*')
101
+ .replace(/\{\{GLOBSTAR_SLASH\}\}/g, '([^/]+/)*') // zero or more directories
102
+ .replace(/\{\{GLOBSTAR\}\}/g, '.*')
103
+ .replace(/\?/g, '[^/]');
104
+ const regex = new RegExp(`^${regexStr}$`);
105
+ if (regex.test(filePath))
106
+ return true;
107
+ // Also check if the pattern matches as a directory prefix
108
+ const dirRegex = new RegExp(`(^|/)${regexStr}(/|$)`);
109
+ return dirRegex.test(filePath);
110
+ }
111
+ /**
112
+ * Load ignore patterns from a .shieldignore file, resolving relative to a base directory.
113
+ */
114
+ function loadIgnorePatterns(basePath, customIgnorePath) {
115
+ const patterns = [];
116
+ // Load from default .shieldignore in base path
117
+ const defaultIgnore = path.join(basePath, '.shieldignore');
118
+ patterns.push(...parseShieldIgnore(defaultIgnore));
119
+ // Load from custom path if provided
120
+ if (customIgnorePath && customIgnorePath !== defaultIgnore) {
121
+ patterns.push(...parseShieldIgnore(customIgnorePath));
122
+ }
123
+ return patterns;
124
+ }
125
+ //# sourceMappingURL=ignore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ignore.js","sourceRoot":"","sources":["../../src/scanner/ignore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { InjectionFinding, Ruleset } from '../types/index.js';
2
+ /**
3
+ * Scan a single file for prompt injection patterns using 2-layer detection.
4
+ *
5
+ * Layer 1: Keyword/pattern matching (direct + indirect patterns)
6
+ * Layer 2: Structural analysis (comments, zero-width chars, tool length)
7
+ *
8
+ * Cross-judgment:
9
+ * - Layer 1 + Layer 2 = critical
10
+ * - Layer 1 only = warning
11
+ * - Layer 2 only (zero-width/comment with injection) = warning
12
+ * - Encoded bypass (Base64/URL) = automatic critical
13
+ */
14
+ export declare function scanFileInjection(content: string, filePath: string, ruleset: Ruleset): InjectionFinding[];
15
+ //# sourceMappingURL=injection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injection.d.ts","sourceRoot":"","sources":["../../src/scanner/injection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAoB,OAAO,EAAE,MAAM,mBAAmB,CAAC;AA8IrF;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,GACf,gBAAgB,EAAE,CAiHpB"}
@@ -0,0 +1,234 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.scanFileInjection = scanFileInjection;
4
+ const ignore_js_1 = require("./ignore.js");
5
+ /**
6
+ * Extract surrounding context (up to 50 chars) around a match position.
7
+ */
8
+ function extractContext(line, matchIdx, matchLen) {
9
+ const contextRadius = 25;
10
+ const start = Math.max(0, matchIdx - contextRadius);
11
+ const end = Math.min(line.length, matchIdx + matchLen + contextRadius);
12
+ let ctx = line.substring(start, end).trim();
13
+ if (ctx.length > 50) {
14
+ ctx = ctx.substring(0, 50);
15
+ }
16
+ return ctx;
17
+ }
18
+ /**
19
+ * Layer 1: Keyword/pattern matching against a line.
20
+ */
21
+ function keywordLayer(line, patterns) {
22
+ const hits = [];
23
+ for (const pattern of patterns) {
24
+ const regex = new RegExp(pattern.regex, 'gi');
25
+ let match;
26
+ while ((match = regex.exec(line)) !== null) {
27
+ hits.push({ pattern, match });
28
+ }
29
+ }
30
+ return hits;
31
+ }
32
+ /**
33
+ * Check if text contains a Base64 encoded string, decode it, and re-check patterns.
34
+ */
35
+ function decodeAndCheck(text, allPatterns) {
36
+ // Match Base64 strings (at least 20 chars to reduce FP)
37
+ const base64Regex = /[A-Za-z0-9+/]{20,}={0,2}/g;
38
+ let b64Match;
39
+ while ((b64Match = base64Regex.exec(text)) !== null) {
40
+ try {
41
+ const decoded = Buffer.from(b64Match[0], 'base64').toString('utf-8');
42
+ // Check if decoded text is printable (reduce FP from random base64)
43
+ if (!/^[\x20-\x7E\s]{4,}$/.test(decoded))
44
+ continue;
45
+ const hits = keywordLayer(decoded, allPatterns);
46
+ if (hits.length > 0) {
47
+ return { decoded, hits };
48
+ }
49
+ }
50
+ catch {
51
+ // Not valid base64, skip
52
+ }
53
+ }
54
+ // URL encoding check
55
+ if (text.includes('%')) {
56
+ try {
57
+ const decoded = decodeURIComponent(text);
58
+ if (decoded !== text) {
59
+ const hits = keywordLayer(decoded, allPatterns);
60
+ if (hits.length > 0) {
61
+ return { decoded, hits };
62
+ }
63
+ }
64
+ }
65
+ catch {
66
+ // Not valid URL encoding, skip
67
+ }
68
+ }
69
+ return null;
70
+ }
71
+ /**
72
+ * Layer 2: Structural analysis on content/line.
73
+ */
74
+ function structureLayer(fullContent, line, lineIdx, ruleset) {
75
+ const structural = ruleset.injection.structural;
76
+ // Check if line is inside an HTML comment
77
+ let inComment = false;
78
+ let commentText;
79
+ const htmlCommentRegex = new RegExp(structural.html_comment_regex, 'g');
80
+ let htmlMatch;
81
+ while ((htmlMatch = htmlCommentRegex.exec(fullContent)) !== null) {
82
+ const commentStart = fullContent.substring(0, htmlMatch.index).split('\n').length - 1;
83
+ const commentEnd = fullContent.substring(0, htmlMatch.index + htmlMatch[0].length).split('\n').length - 1;
84
+ if (lineIdx >= commentStart && lineIdx <= commentEnd) {
85
+ inComment = true;
86
+ commentText = htmlMatch[0].replace(/<!--\s*/, '').replace(/\s*-->/, '');
87
+ break;
88
+ }
89
+ }
90
+ // Check for markdown comments
91
+ if (!inComment) {
92
+ const mdCommentRegex = new RegExp(structural.markdown_comment_regex, 'g');
93
+ let mdMatch;
94
+ while ((mdMatch = mdCommentRegex.exec(line)) !== null) {
95
+ inComment = true;
96
+ commentText = mdMatch[0];
97
+ break;
98
+ }
99
+ }
100
+ // Check for zero-width characters
101
+ const zeroWidthChars = ['\u200B', '\u200C', '\u200D', '\uFEFF', '\u2060'];
102
+ const hasZeroWidth = zeroWidthChars.some(ch => line.includes(ch));
103
+ // Tool description length anomaly (for JSON files with tool descriptions)
104
+ let toolLengthAnomaly = false;
105
+ try {
106
+ if (line.includes('"description"')) {
107
+ const descMatch = /"description"\s*:\s*"([^"]*)"/.exec(line);
108
+ if (descMatch && descMatch[1].length > 200 * structural.tool_length_multiplier) {
109
+ toolLengthAnomaly = true;
110
+ }
111
+ }
112
+ }
113
+ catch {
114
+ // Ignore parsing errors
115
+ }
116
+ return { inComment, hasZeroWidth, toolLengthAnomaly, commentText };
117
+ }
118
+ /**
119
+ * Scan a single file for prompt injection patterns using 2-layer detection.
120
+ *
121
+ * Layer 1: Keyword/pattern matching (direct + indirect patterns)
122
+ * Layer 2: Structural analysis (comments, zero-width chars, tool length)
123
+ *
124
+ * Cross-judgment:
125
+ * - Layer 1 + Layer 2 = critical
126
+ * - Layer 1 only = warning
127
+ * - Layer 2 only (zero-width/comment with injection) = warning
128
+ * - Encoded bypass (Base64/URL) = automatic critical
129
+ */
130
+ function scanFileInjection(content, filePath, ruleset) {
131
+ const findings = [];
132
+ const lines = content.split('\n');
133
+ const allPatterns = [
134
+ ...ruleset.injection.direct_patterns,
135
+ ...ruleset.injection.indirect_patterns,
136
+ ];
137
+ for (let i = 0; i < lines.length; i++) {
138
+ const line = lines[i];
139
+ const lineNum = i + 1;
140
+ if ((0, ignore_js_1.isLineIgnored)(line))
141
+ continue;
142
+ // Layer 1: Keyword matching
143
+ const directHits = keywordLayer(line, ruleset.injection.direct_patterns);
144
+ const indirectHits = keywordLayer(line, ruleset.injection.indirect_patterns);
145
+ const allHits = [...directHits, ...indirectHits];
146
+ const hasKeyword = allHits.length > 0;
147
+ // Layer 2: Structural analysis
148
+ const structure = structureLayer(content, line, i, ruleset);
149
+ const hasStructure = structure.inComment || structure.hasZeroWidth || structure.toolLengthAnomaly;
150
+ // Check for encoded injection
151
+ const encodedResult = decodeAndCheck(line, allPatterns);
152
+ if (encodedResult) {
153
+ const firstHit = encodedResult.hits[0];
154
+ findings.push({
155
+ file: filePath,
156
+ line: lineNum,
157
+ type: 'encoded',
158
+ severity: 'critical',
159
+ layers: { keyword: true, structure: false },
160
+ pattern: firstHit.pattern.id,
161
+ context: extractContext(line, 0, Math.min(line.length, 50)),
162
+ description: `Encoded injection detected (${firstHit.pattern.description})`,
163
+ });
164
+ continue; // Don't double-report
165
+ }
166
+ // Cross-judgment for keyword hits
167
+ if (hasKeyword) {
168
+ for (const hit of allHits) {
169
+ const matchIdx = hit.match.index ?? 0;
170
+ const severity = hasStructure ? 'critical' : 'warning';
171
+ const type = hit.pattern.type === 'direct' ? 'direct' : 'indirect';
172
+ findings.push({
173
+ file: filePath,
174
+ line: lineNum,
175
+ type,
176
+ severity,
177
+ layers: { keyword: true, structure: hasStructure },
178
+ pattern: hit.pattern.id,
179
+ context: extractContext(line, matchIdx, hit.match[0].length),
180
+ description: hit.pattern.description,
181
+ });
182
+ }
183
+ }
184
+ // Structure-only findings
185
+ if (!hasKeyword && hasStructure) {
186
+ // For comments, re-check the comment text for injection patterns
187
+ if (structure.inComment && structure.commentText) {
188
+ const commentHits = keywordLayer(structure.commentText, allPatterns);
189
+ if (commentHits.length > 0) {
190
+ for (const hit of commentHits) {
191
+ findings.push({
192
+ file: filePath,
193
+ line: lineNum,
194
+ type: 'structural',
195
+ severity: 'critical',
196
+ layers: { keyword: true, structure: true },
197
+ pattern: hit.pattern.id,
198
+ context: extractContext(line, 0, Math.min(line.length, 50)),
199
+ description: `Hidden injection in comment (${hit.pattern.description})`,
200
+ });
201
+ }
202
+ }
203
+ }
204
+ // Zero-width character detection
205
+ if (structure.hasZeroWidth) {
206
+ findings.push({
207
+ file: filePath,
208
+ line: lineNum,
209
+ type: 'structural',
210
+ severity: 'warning',
211
+ layers: { keyword: false, structure: true },
212
+ pattern: 'zero_width_chars',
213
+ context: extractContext(line, 0, Math.min(line.length, 50)),
214
+ description: 'Zero-width Unicode characters detected (potential text hiding)',
215
+ });
216
+ }
217
+ // Tool length anomaly
218
+ if (structure.toolLengthAnomaly) {
219
+ findings.push({
220
+ file: filePath,
221
+ line: lineNum,
222
+ type: 'structural',
223
+ severity: 'warning',
224
+ layers: { keyword: false, structure: true },
225
+ pattern: 'tool_length_anomaly',
226
+ context: extractContext(line, 0, Math.min(line.length, 50)),
227
+ description: 'Abnormally long tool description (potential injection payload)',
228
+ });
229
+ }
230
+ }
231
+ }
232
+ return findings;
233
+ }
234
+ //# sourceMappingURL=injection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injection.js","sourceRoot":"","sources":["../../src/scanner/injection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { MCPFinding, SecretFinding, Ruleset } from '../types/index.js';
2
+ /**
3
+ * Scan for MCP configuration files and check 5 security items.
4
+ */
5
+ export declare function scanMCPConfigs(targetPath: string, ruleset: Ruleset, secretsFindings: SecretFinding[]): Promise<MCPFinding[]>;
6
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/scanner/mcp.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,UAAU,EAEV,aAAa,EACb,OAAO,EACR,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,eAAe,EAAE,aAAa,EAAE,GAC/B,OAAO,CAAC,UAAU,EAAE,CAAC,CAiCvB"}