acidtest 0.1.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 (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +104 -0
  3. package/dist/index.d.ts +7 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +170 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/layers/code.d.ts +10 -0
  8. package/dist/layers/code.d.ts.map +1 -0
  9. package/dist/layers/code.js +196 -0
  10. package/dist/layers/code.js.map +1 -0
  11. package/dist/layers/crossref.d.ts +10 -0
  12. package/dist/layers/crossref.d.ts.map +1 -0
  13. package/dist/layers/crossref.js +143 -0
  14. package/dist/layers/crossref.js.map +1 -0
  15. package/dist/layers/injection.d.ts +10 -0
  16. package/dist/layers/injection.d.ts.map +1 -0
  17. package/dist/layers/injection.js +88 -0
  18. package/dist/layers/injection.js.map +1 -0
  19. package/dist/layers/permissions.d.ts +10 -0
  20. package/dist/layers/permissions.d.ts.map +1 -0
  21. package/dist/layers/permissions.js +120 -0
  22. package/dist/layers/permissions.js.map +1 -0
  23. package/dist/pattern-loader.d.ts +14 -0
  24. package/dist/pattern-loader.d.ts.map +1 -0
  25. package/dist/pattern-loader.js +50 -0
  26. package/dist/pattern-loader.js.map +1 -0
  27. package/dist/patterns/credential-patterns.json +77 -0
  28. package/dist/patterns/dangerous-imports.json +113 -0
  29. package/dist/patterns/exfiltration-sinks.json +77 -0
  30. package/dist/patterns/obfuscation.json +65 -0
  31. package/dist/patterns/prompt-injection.json +125 -0
  32. package/dist/patterns/sensitive-paths.json +89 -0
  33. package/dist/reporter.d.ts +14 -0
  34. package/dist/reporter.d.ts.map +1 -0
  35. package/dist/reporter.js +175 -0
  36. package/dist/reporter.js.map +1 -0
  37. package/dist/scanner.d.ts +15 -0
  38. package/dist/scanner.d.ts.map +1 -0
  39. package/dist/scanner.js +176 -0
  40. package/dist/scanner.js.map +1 -0
  41. package/dist/scoring.d.ts +23 -0
  42. package/dist/scoring.d.ts.map +1 -0
  43. package/dist/scoring.js +85 -0
  44. package/dist/scoring.js.map +1 -0
  45. package/dist/types.d.ts +112 -0
  46. package/dist/types.d.ts.map +1 -0
  47. package/dist/types.js +5 -0
  48. package/dist/types.js.map +1 -0
  49. package/package.json +46 -0
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Layer 4: Cross-Reference Analysis
3
+ * Compares findings across layers to detect permission mismatches and deception
4
+ */
5
+ /**
6
+ * Cross-reference findings from previous layers
7
+ */
8
+ export async function scanCrossReference(skill, previousFindings) {
9
+ const findings = [];
10
+ const metadata = skill.metadata;
11
+ // Extract findings by category
12
+ const networkFindings = previousFindings.filter(f => f.category.includes('network') ||
13
+ f.category === 'exfiltration-sinks' ||
14
+ f.patternId?.startsWith('ex-'));
15
+ const shellFindings = previousFindings.filter(f => f.category.includes('child_process') ||
16
+ f.category.includes('shell') ||
17
+ f.patternId === 'di-001');
18
+ const fileSystemFindings = previousFindings.filter(f => f.category.includes('filesystem') ||
19
+ f.category.includes('sensitive-paths') ||
20
+ f.patternId?.startsWith('sp-'));
21
+ const envAccessFindings = previousFindings.filter(f => f.patternId === 'cp-006' // process.env access
22
+ );
23
+ // Get declared permissions
24
+ const allowedTools = metadata['allowed-tools'] || [];
25
+ const allowedBins = metadata.bins || [];
26
+ const allowedEnv = metadata.env || [];
27
+ // Check for network capability mismatches
28
+ if (networkFindings.length > 0) {
29
+ const declaredNetwork = allowedTools.some(tool => ['browser', 'http', 'fetch', 'network', 'web', 'curl', 'wget'].some(net => tool.toLowerCase().includes(net))) || allowedBins.some(bin => ['curl', 'wget'].some(net => bin.toLowerCase().includes(net)));
30
+ if (!declaredNetwork) {
31
+ findings.push({
32
+ severity: 'CRITICAL',
33
+ category: 'permission-mismatch',
34
+ title: 'Undeclared network access',
35
+ detail: 'Code makes network calls but skill does not declare network permissions',
36
+ evidence: `Found ${networkFindings.length} network-related finding(s) in code`
37
+ });
38
+ }
39
+ }
40
+ // Check for shell execution mismatches
41
+ if (shellFindings.length > 0) {
42
+ const declaredShell = allowedTools.some(tool => ['shell', 'bash', 'exec', 'command'].some(sh => tool.toLowerCase().includes(sh))) || allowedBins.some(bin => ['bash', 'sh', 'zsh', 'fish', 'cmd', 'powershell'].some(sh => bin.toLowerCase() === sh));
43
+ if (!declaredShell) {
44
+ findings.push({
45
+ severity: 'CRITICAL',
46
+ category: 'permission-mismatch',
47
+ title: 'Undeclared shell execution',
48
+ detail: 'Code executes shell commands but skill does not declare shell permissions',
49
+ evidence: `Found ${shellFindings.length} shell-related finding(s) in code`
50
+ });
51
+ }
52
+ }
53
+ // Check for file system access mismatches
54
+ if (fileSystemFindings.length > 0) {
55
+ const declaredFS = allowedTools.some(tool => ['file', 'filesystem', 'fs', 'read', 'write'].some(fs => tool.toLowerCase().includes(fs)));
56
+ if (!declaredFS) {
57
+ findings.push({
58
+ severity: 'HIGH',
59
+ category: 'permission-mismatch',
60
+ title: 'Undeclared file system access',
61
+ detail: 'Code accesses sensitive file paths but skill does not declare filesystem permissions',
62
+ evidence: `Found ${fileSystemFindings.length} filesystem-related finding(s) in code`
63
+ });
64
+ }
65
+ }
66
+ // Check for environment variable mismatches
67
+ if (envAccessFindings.length > 0 && skill.codeFiles.length > 0) {
68
+ // Extract environment variables accessed in code
69
+ const codeEnvVars = extractEnvVarsFromCode(skill.codeFiles);
70
+ // Find undeclared env vars
71
+ const undeclaredEnvVars = codeEnvVars.filter(envVar => !allowedEnv.includes(envVar));
72
+ if (undeclaredEnvVars.length > 0) {
73
+ findings.push({
74
+ severity: 'HIGH',
75
+ category: 'permission-mismatch',
76
+ title: 'Undeclared environment variable access',
77
+ detail: 'Code accesses environment variables not declared in skill metadata',
78
+ evidence: `Undeclared variables: ${undeclaredEnvVars.slice(0, 5).join(', ')}${undeclaredEnvVars.length > 5 ? '...' : ''}`
79
+ });
80
+ }
81
+ }
82
+ // Check for deception indicators
83
+ const description = (metadata.description || '').toLowerCase();
84
+ const benignKeywords = ['calculator', 'timer', 'note', 'reminder', 'formatter', 'converter'];
85
+ const seemsBenign = benignKeywords.some(kw => description.includes(kw));
86
+ if (seemsBenign && networkFindings.length > 0) {
87
+ findings.push({
88
+ severity: 'HIGH',
89
+ category: 'deception-indicator',
90
+ title: 'Benign description with network access',
91
+ detail: `Skill claims to be a "${metadata.description}" but makes network calls`,
92
+ evidence: 'Simple utility skills typically do not require network access'
93
+ });
94
+ }
95
+ // Check for supply chain indicators
96
+ if (skill.codeFiles.length > 0) {
97
+ // Check for suspiciously large code files for simple functionality
98
+ const totalCodeSize = skill.codeFiles.reduce((sum, f) => sum + f.content.length, 0);
99
+ if (totalCodeSize > 100000 && seemsBenign) {
100
+ findings.push({
101
+ severity: 'MEDIUM',
102
+ category: 'supply-chain-risk',
103
+ title: 'Unusually large code for stated purpose',
104
+ detail: `Code is ${totalCodeSize} characters but skill description suggests simple functionality`,
105
+ evidence: 'Large code size may indicate hidden functionality'
106
+ });
107
+ }
108
+ // Check for minified code
109
+ const hasMinified = skill.codeFiles.some(f => {
110
+ const lines = f.content.split('\n');
111
+ const avgLineLength = f.content.length / lines.length;
112
+ return avgLineLength > 200; // Average line > 200 chars suggests minification
113
+ });
114
+ if (hasMinified) {
115
+ findings.push({
116
+ severity: 'MEDIUM',
117
+ category: 'supply-chain-risk',
118
+ title: 'Minified or obfuscated code detected',
119
+ detail: 'Code appears to be minified or obfuscated',
120
+ evidence: 'Minified code is harder to audit and may hide malicious behavior'
121
+ });
122
+ }
123
+ }
124
+ return {
125
+ layer: 'crossref',
126
+ findings
127
+ };
128
+ }
129
+ /**
130
+ * Extract environment variable names accessed in code
131
+ */
132
+ function extractEnvVarsFromCode(codeFiles) {
133
+ const envVars = new Set();
134
+ const envPattern = /process\.env\.([A-Z_][A-Z0-9_]*)/g;
135
+ for (const file of codeFiles) {
136
+ let match;
137
+ while ((match = envPattern.exec(file.content)) !== null) {
138
+ envVars.add(match[1]);
139
+ }
140
+ }
141
+ return Array.from(envVars);
142
+ }
143
+ //# sourceMappingURL=crossref.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crossref.js","sourceRoot":"","sources":["../../src/layers/crossref.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Layer 2: Prompt Injection Scan
3
+ * Scans markdown content for prompt injection patterns
4
+ */
5
+ import type { Skill, LayerResult } from '../types.js';
6
+ /**
7
+ * Scan markdown content for prompt injection patterns
8
+ */
9
+ export declare function scanInjection(skill: Skill): Promise<LayerResult>;
10
+ //# sourceMappingURL=injection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injection.d.ts","sourceRoot":"","sources":["../../src/layers/injection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAW,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/D;;GAEG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,CAmEtE"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Layer 2: Prompt Injection Scan
3
+ * Scans markdown content for prompt injection patterns
4
+ */
5
+ import { loadPatterns } from '../pattern-loader.js';
6
+ /**
7
+ * Scan markdown content for prompt injection patterns
8
+ */
9
+ export async function scanInjection(skill) {
10
+ const findings = [];
11
+ const markdown = skill.markdownContent;
12
+ // Load prompt injection and sensitive path patterns
13
+ const promptPatterns = await loadPatterns('prompt-injection');
14
+ const pathPatterns = await loadPatterns('sensitive-paths');
15
+ // Combine patterns that apply to markdown layer
16
+ const allPatterns = [...promptPatterns, ...pathPatterns].filter(p => p.layer === 'markdown');
17
+ // Scan against each pattern
18
+ for (const pattern of allPatterns) {
19
+ const regex = new RegExp(pattern.match.value, pattern.match.flags || '');
20
+ const matches = markdown.match(regex);
21
+ if (matches && matches.length > 0) {
22
+ // Try to find line number for the match
23
+ const lineNumber = findLineNumber(markdown, matches[0]);
24
+ findings.push({
25
+ severity: pattern.severity,
26
+ category: pattern.category || 'prompt-injection',
27
+ title: pattern.name,
28
+ file: 'SKILL.md',
29
+ line: lineNumber,
30
+ detail: pattern.description || `Pattern match: ${pattern.name}`,
31
+ evidence: matches.length > 1 ? `${matches.length} matches found` : `Match: "${truncate(matches[0], 100)}"`,
32
+ patternId: pattern.id
33
+ });
34
+ }
35
+ }
36
+ // Additional heuristic checks
37
+ // Check for excessively long markdown (could hide malicious content)
38
+ if (markdown.length > 50000) {
39
+ findings.push({
40
+ severity: 'LOW',
41
+ category: 'suspicious-size',
42
+ title: 'Unusually large skill documentation',
43
+ file: 'SKILL.md',
44
+ detail: `Skill documentation is ${markdown.length} characters`,
45
+ evidence: 'Large files can hide malicious content'
46
+ });
47
+ }
48
+ // Check for base64-looking strings in markdown (potential obfuscation)
49
+ const base64Pattern = /[A-Za-z0-9+\/]{50,}={0,2}/g;
50
+ const base64Matches = markdown.match(base64Pattern);
51
+ if (base64Matches && base64Matches.length > 0) {
52
+ findings.push({
53
+ severity: 'MEDIUM',
54
+ category: 'obfuscation',
55
+ title: 'Possible base64-encoded content in markdown',
56
+ file: 'SKILL.md',
57
+ detail: `Found ${base64Matches.length} base64-looking string(s)`,
58
+ evidence: 'Base64 encoding can hide malicious instructions'
59
+ });
60
+ }
61
+ return {
62
+ layer: 'markdown',
63
+ findings
64
+ };
65
+ }
66
+ /**
67
+ * Find line number for a match in text
68
+ */
69
+ function findLineNumber(text, match) {
70
+ const index = text.indexOf(match);
71
+ if (index === -1)
72
+ return undefined;
73
+ const beforeMatch = text.substring(0, index);
74
+ const lineNumber = beforeMatch.split('\n').length;
75
+ return lineNumber;
76
+ }
77
+ /**
78
+ * Truncate string for display
79
+ */
80
+ function truncate(str, maxLength) {
81
+ // Remove newlines and excessive whitespace
82
+ const cleaned = str.replace(/\s+/g, ' ').trim();
83
+ if (cleaned.length <= maxLength) {
84
+ return cleaned;
85
+ }
86
+ return cleaned.substring(0, maxLength) + '...';
87
+ }
88
+ //# sourceMappingURL=injection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injection.js","sourceRoot":"","sources":["../../src/layers/injection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Layer 1: Permission Audit
3
+ * Analyzes YAML frontmatter to identify requested permissions and assess risk
4
+ */
5
+ import type { Skill, LayerResult } from '../types.js';
6
+ /**
7
+ * Scan skill permissions from YAML frontmatter
8
+ */
9
+ export declare function scanPermissions(skill: Skill): Promise<LayerResult>;
10
+ //# sourceMappingURL=permissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/layers/permissions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAW,WAAW,EAAW,MAAM,aAAa,CAAC;AAGxE;;GAEG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,CAiIxE"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Layer 1: Permission Audit
3
+ * Analyzes YAML frontmatter to identify requested permissions and assess risk
4
+ */
5
+ import { loadPatterns } from '../pattern-loader.js';
6
+ /**
7
+ * Scan skill permissions from YAML frontmatter
8
+ */
9
+ export async function scanPermissions(skill) {
10
+ const findings = [];
11
+ const metadata = skill.metadata;
12
+ // Load credential patterns for environment variable scanning
13
+ const credentialPatterns = await loadPatterns('credential-patterns');
14
+ // Check for no declared permissions (suspicious)
15
+ if (!metadata.bins && !metadata.env && !metadata['allowed-tools']) {
16
+ findings.push({
17
+ severity: 'LOW',
18
+ category: 'permissions',
19
+ title: 'No declared permissions',
20
+ file: 'SKILL.md',
21
+ detail: 'Skill declares no permissions (bins, env, or allowed-tools)',
22
+ evidence: 'Legitimate skills typically declare at least one permission'
23
+ });
24
+ }
25
+ // Scan environment variables for credential patterns
26
+ if (metadata.env && Array.isArray(metadata.env)) {
27
+ for (const envVar of metadata.env) {
28
+ for (const pattern of credentialPatterns) {
29
+ if (pattern.layer !== 'permissions')
30
+ continue;
31
+ const regex = new RegExp(pattern.match.value, pattern.match.flags);
32
+ if (regex.test(envVar)) {
33
+ findings.push({
34
+ severity: pattern.severity,
35
+ category: 'credential-request',
36
+ title: pattern.name,
37
+ file: 'SKILL.md',
38
+ detail: `Requests credential environment variable: ${envVar}`,
39
+ evidence: pattern.description,
40
+ patternId: pattern.id
41
+ });
42
+ }
43
+ }
44
+ }
45
+ }
46
+ // Check allowed-tools for dangerous permissions
47
+ if (metadata['allowed-tools'] && Array.isArray(metadata['allowed-tools'])) {
48
+ const tools = metadata['allowed-tools'];
49
+ // Check for shell/command execution
50
+ const shellTools = ['shell', 'bash', 'exec', 'command'];
51
+ const hasShell = tools.some(tool => shellTools.some(shellTool => tool.toLowerCase().includes(shellTool)));
52
+ if (hasShell) {
53
+ findings.push({
54
+ severity: 'CRITICAL',
55
+ category: 'dangerous-permission',
56
+ title: 'Shell execution permission',
57
+ file: 'SKILL.md',
58
+ detail: 'Skill requests shell/command execution capability',
59
+ evidence: `Allowed tools: ${tools.filter(t => shellTools.some(st => t.toLowerCase().includes(st))).join(', ')}`
60
+ });
61
+ }
62
+ // Check for network access
63
+ const networkTools = ['browser', 'http', 'fetch', 'network', 'web', 'curl', 'wget'];
64
+ const hasNetwork = tools.some(tool => networkTools.some(netTool => tool.toLowerCase().includes(netTool)));
65
+ if (hasNetwork) {
66
+ findings.push({
67
+ severity: 'HIGH',
68
+ category: 'network-permission',
69
+ title: 'Network access permission',
70
+ file: 'SKILL.md',
71
+ detail: 'Skill requests network/HTTP access capability',
72
+ evidence: `Allowed tools: ${tools.filter(t => networkTools.some(nt => t.toLowerCase().includes(nt))).join(', ')}`
73
+ });
74
+ }
75
+ // Check for file system access
76
+ const fsTools = ['file', 'filesystem', 'fs', 'read', 'write'];
77
+ const hasFileSystem = tools.some(tool => fsTools.some(fsTool => tool.toLowerCase().includes(fsTool)));
78
+ if (hasFileSystem) {
79
+ findings.push({
80
+ severity: 'MEDIUM',
81
+ category: 'filesystem-permission',
82
+ title: 'File system access permission',
83
+ file: 'SKILL.md',
84
+ detail: 'Skill requests file system access capability',
85
+ evidence: `Allowed tools: ${tools.filter(t => fsTools.some(ft => t.toLowerCase().includes(ft))).join(', ')}`
86
+ });
87
+ }
88
+ }
89
+ // Check for dangerous system binaries
90
+ if (metadata.bins && Array.isArray(metadata.bins)) {
91
+ const dangerousBins = [
92
+ { pattern: /^(bash|sh|zsh|fish|cmd|powershell)$/i, severity: 'CRITICAL', reason: 'Shell interpreter' },
93
+ { pattern: /^(curl|wget|fetch)$/i, severity: 'HIGH', reason: 'Network download tool' },
94
+ { pattern: /^(nc|netcat|ncat)$/i, severity: 'CRITICAL', reason: 'Network connection tool' },
95
+ { pattern: /^(python|node|ruby|perl|php)$/i, severity: 'HIGH', reason: 'Script interpreter' },
96
+ { pattern: /^(docker|kubectl|podman)$/i, severity: 'HIGH', reason: 'Container management' },
97
+ { pattern: /^(ssh|scp|sftp)$/i, severity: 'HIGH', reason: 'Remote access tool' },
98
+ { pattern: /^(git)$/i, severity: 'MEDIUM', reason: 'Version control (can clone arbitrary repos)' }
99
+ ];
100
+ for (const bin of metadata.bins) {
101
+ for (const dangerous of dangerousBins) {
102
+ if (dangerous.pattern.test(bin)) {
103
+ findings.push({
104
+ severity: dangerous.severity,
105
+ category: 'dangerous-binary',
106
+ title: `Dangerous binary: ${bin}`,
107
+ file: 'SKILL.md',
108
+ detail: `Requests access to system binary: ${bin}`,
109
+ evidence: dangerous.reason
110
+ });
111
+ }
112
+ }
113
+ }
114
+ }
115
+ return {
116
+ layer: 'permissions',
117
+ findings
118
+ };
119
+ }
120
+ //# sourceMappingURL=permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/layers/permissions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Pattern loader utility
3
+ * Loads detection patterns from JSON files
4
+ */
5
+ import type { Pattern } from './types.js';
6
+ /**
7
+ * Load patterns from a specific category file
8
+ */
9
+ export declare function loadPatterns(category: string): Promise<Pattern[]>;
10
+ /**
11
+ * Load all available patterns
12
+ */
13
+ export declare function loadAllPatterns(): Promise<Pattern[]>;
14
+ //# sourceMappingURL=pattern-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-loader.d.ts","sourceRoot":"","sources":["../src/pattern-loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAmB,MAAM,YAAY,CAAC;AAO3D;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAiBvE;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAkB1D"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Pattern loader utility
3
+ * Loads detection patterns from JSON files
4
+ */
5
+ import { readFileSync } from 'fs';
6
+ import { join, dirname } from 'path';
7
+ import { fileURLToPath } from 'url';
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+ const patternCache = new Map();
11
+ /**
12
+ * Load patterns from a specific category file
13
+ */
14
+ export async function loadPatterns(category) {
15
+ // Check cache first
16
+ if (patternCache.has(category)) {
17
+ return patternCache.get(category);
18
+ }
19
+ try {
20
+ const patternPath = join(__dirname, 'patterns', `${category}.json`);
21
+ const content = readFileSync(patternPath, 'utf-8');
22
+ const data = JSON.parse(content);
23
+ patternCache.set(category, data.patterns);
24
+ return data.patterns;
25
+ }
26
+ catch (error) {
27
+ console.warn(`Warning: Could not load patterns for category: ${category}`);
28
+ return [];
29
+ }
30
+ }
31
+ /**
32
+ * Load all available patterns
33
+ */
34
+ export async function loadAllPatterns() {
35
+ const categories = [
36
+ 'prompt-injection',
37
+ 'dangerous-imports',
38
+ 'sensitive-paths',
39
+ 'exfiltration-sinks',
40
+ 'obfuscation',
41
+ 'credential-patterns'
42
+ ];
43
+ const allPatterns = [];
44
+ for (const category of categories) {
45
+ const patterns = await loadPatterns(category);
46
+ allPatterns.push(...patterns);
47
+ }
48
+ return allPatterns;
49
+ }
50
+ //# sourceMappingURL=pattern-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-loader.js","sourceRoot":"","sources":["../src/pattern-loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAGpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,MAAM,YAAY,GAAG,IAAI,GAAG,EAAqB,CAAC;AAElD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,oBAAoB;IACpB,IAAI,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC/B,OAAO,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC;IACrC,CAAC;IAED,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,QAAQ,OAAO,CAAC,CAAC;QACpE,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,IAAI,GAAoB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAElD,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,kDAAkD,QAAQ,EAAE,CAAC,CAAC;QAC3E,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,UAAU,GAAG;QACjB,kBAAkB;QAClB,mBAAmB;QACnB,iBAAiB;QACjB,oBAAoB;QACpB,aAAa;QACb,qBAAqB;KACtB,CAAC;IAEF,MAAM,WAAW,GAAc,EAAE,CAAC;IAElC,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC9C,WAAW,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1,77 @@
1
+ {
2
+ "category": "credential-patterns",
3
+ "patterns": [
4
+ {
5
+ "id": "cp-001",
6
+ "name": "env-var-api-key",
7
+ "description": "Requests API key environment variable",
8
+ "severity": "HIGH",
9
+ "match": {
10
+ "type": "regex",
11
+ "value": "(API_KEY|APIKEY|API_SECRET)",
12
+ "flags": "g"
13
+ },
14
+ "layer": "permissions"
15
+ },
16
+ {
17
+ "id": "cp-002",
18
+ "name": "env-var-token",
19
+ "description": "Requests token environment variable",
20
+ "severity": "HIGH",
21
+ "match": {
22
+ "type": "regex",
23
+ "value": "(TOKEN|ACCESS_TOKEN|AUTH_TOKEN|BEARER_TOKEN)",
24
+ "flags": "g"
25
+ },
26
+ "layer": "permissions"
27
+ },
28
+ {
29
+ "id": "cp-003",
30
+ "name": "env-var-password",
31
+ "description": "Requests password environment variable",
32
+ "severity": "HIGH",
33
+ "match": {
34
+ "type": "regex",
35
+ "value": "(PASSWORD|PASSWD|PWD)(?!_HASH)",
36
+ "flags": "g"
37
+ },
38
+ "layer": "permissions"
39
+ },
40
+ {
41
+ "id": "cp-004",
42
+ "name": "env-var-secret",
43
+ "description": "Requests secret environment variable",
44
+ "severity": "HIGH",
45
+ "match": {
46
+ "type": "regex",
47
+ "value": "(SECRET|CLIENT_SECRET)",
48
+ "flags": "g"
49
+ },
50
+ "layer": "permissions"
51
+ },
52
+ {
53
+ "id": "cp-005",
54
+ "name": "env-var-credential",
55
+ "description": "Requests credential environment variable",
56
+ "severity": "HIGH",
57
+ "match": {
58
+ "type": "regex",
59
+ "value": "(CREDENTIAL|CREDENTIALS)",
60
+ "flags": "g"
61
+ },
62
+ "layer": "permissions"
63
+ },
64
+ {
65
+ "id": "cp-006",
66
+ "name": "process-env-access",
67
+ "description": "Accesses process.env in code",
68
+ "severity": "MEDIUM",
69
+ "match": {
70
+ "type": "regex",
71
+ "value": "process\\.env\\.[A-Z_]+",
72
+ "flags": "g"
73
+ },
74
+ "layer": "code"
75
+ }
76
+ ]
77
+ }