code-sentinel-mcp 0.2.3 → 0.2.5

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.
@@ -1,214 +1,7 @@
1
- const errorPatterns = [
2
- // Unhandled promises
3
- {
4
- id: 'CS-ERR001',
5
- pattern: /(?:^|\s)(?:await\s+)?(?:\w+\.)+\w+\s*\([^)]*\)\s*;?\s*$/gm,
6
- title: 'Potentially Unhandled Promise',
7
- description: 'Async call without await or .then()/.catch() may silently fail.',
8
- severity: 'medium',
9
- category: 'error',
10
- suggestion: 'Use await with try/catch or add .catch() handler.'
11
- },
12
- // Missing error handling
13
- {
14
- id: 'CS-ERR010',
15
- pattern: /async\s+(?:function\s+\w+|\w+\s*=\s*async)\s*\([^)]*\)\s*(?::\s*\w+\s*)?\{(?:(?!try\s*\{).)*\}/gs,
16
- title: 'Async Function Without Try/Catch',
17
- description: 'Async function has no error handling.',
18
- severity: 'medium',
19
- category: 'error',
20
- suggestion: 'Wrap async operations in try/catch or handle at call site.'
21
- },
22
- // Variable shadowing and redeclaration
23
- {
24
- id: 'CS-ERR020',
25
- pattern: /var\s+(\w+)[\s\S]*?var\s+\1\s*=/g,
26
- title: 'Variable Redeclaration with var',
27
- description: 'Same variable declared twice with var - potential bug.',
28
- severity: 'medium',
29
- category: 'error',
30
- suggestion: 'Use let/const and avoid redeclaring variables.'
31
- },
32
- // Comparison issues
33
- {
34
- id: 'CS-ERR030',
35
- pattern: /[^!=]==[^=]/g,
36
- title: 'Loose Equality (==)',
37
- description: 'Loose equality can cause unexpected type coercion.',
38
- severity: 'low',
39
- category: 'error',
40
- suggestion: 'Use strict equality (===) instead.'
41
- },
42
- {
43
- id: 'CS-ERR031',
44
- pattern: /!=[^=]/g,
45
- title: 'Loose Inequality (!=)',
46
- description: 'Loose inequality can cause unexpected type coercion.',
47
- severity: 'low',
48
- category: 'error',
49
- suggestion: 'Use strict inequality (!==) instead.'
50
- },
51
- {
52
- id: 'CS-ERR032',
53
- pattern: /if\s*\(\s*\w+\s*=\s*[^=]/g,
54
- title: 'Assignment in Condition',
55
- description: 'Assignment inside if condition - likely meant to use ==.',
56
- severity: 'high',
57
- category: 'error',
58
- suggestion: 'Use === for comparison. If assignment is intentional, wrap in extra parens.'
59
- },
60
- // Null/undefined issues
61
- {
62
- id: 'CS-ERR040',
63
- pattern: /(\w+)\.(\w+)\s*(?:\(|\.)/g,
64
- title: 'Potential Null Reference',
65
- description: 'Accessing property without null check - may throw.',
66
- severity: 'low',
67
- category: 'error',
68
- suggestion: 'Use optional chaining (?.) or add null checks.'
69
- },
70
- // Loop issues
71
- {
72
- id: 'CS-ERR050',
73
- pattern: /for\s*\(\s*(?:var|let)\s+\w+\s+in\s+/g,
74
- title: 'for...in on Array',
75
- description: 'for...in iterates over keys, not values - often wrong for arrays.',
76
- severity: 'medium',
77
- category: 'error',
78
- suggestion: 'Use for...of, forEach(), or traditional for loop for arrays.'
79
- },
80
- {
81
- id: 'CS-ERR051',
82
- pattern: /while\s*\(\s*true\s*\)/g,
83
- title: 'Infinite Loop Pattern',
84
- description: 'while(true) requires explicit break - easy to create infinite loop.',
85
- severity: 'medium',
86
- category: 'error',
87
- suggestion: 'Ensure there is always a reachable break condition.'
88
- },
89
- // Floating point comparison
90
- {
91
- id: 'CS-ERR060',
92
- pattern: /(?:\d+\.\d+|\w+)\s*===?\s*(?:\d+\.\d+|\w+).*?(?:price|amount|total|sum|money|currency|rate)/gi,
93
- title: 'Floating Point Comparison',
94
- description: 'Direct comparison of floats (especially money) can fail due to precision.',
95
- severity: 'high',
96
- category: 'error',
97
- suggestion: 'Use epsilon comparison or integer cents for money.'
98
- },
99
- // Array mutation issues
100
- {
101
- id: 'CS-ERR070',
102
- pattern: /\.forEach\s*\([^)]*\)\s*\{[^}]*(?:\.push|\.pop|\.shift|\.splice)/g,
103
- title: 'Array Mutation During Iteration',
104
- description: 'Modifying array while iterating can cause skipped elements.',
105
- severity: 'high',
106
- category: 'error',
107
- suggestion: 'Create a new array or iterate backwards when mutating.'
108
- },
109
- // parseInt without radix
110
- {
111
- id: 'CS-ERR080',
112
- pattern: /parseInt\s*\(\s*[^,)]+\s*\)(?!\s*,)/g,
113
- title: 'parseInt Without Radix',
114
- description: 'parseInt without radix can give unexpected results.',
115
- severity: 'low',
116
- category: 'error',
117
- suggestion: 'Always specify radix: parseInt(x, 10).'
118
- },
119
- // Unreachable code
120
- {
121
- id: 'CS-ERR090',
122
- pattern: /return\s+[^;]+;\s*\n\s*(?![\s}]|case\s|default:)/g,
123
- title: 'Potentially Unreachable Code',
124
- description: 'Code after return statement will never execute.',
125
- severity: 'medium',
126
- category: 'error',
127
- suggestion: 'Remove unreachable code or fix control flow.'
128
- },
129
- // Dangerous delete
130
- {
131
- id: 'CS-ERR100',
132
- pattern: /delete\s+\w+\[\w+\]/g,
133
- title: 'delete Operator on Array',
134
- description: 'delete leaves holes in arrays - length unchanged.',
135
- severity: 'medium',
136
- category: 'error',
137
- suggestion: 'Use splice() to remove array elements.'
138
- },
139
- // This binding issues
140
- {
141
- id: 'CS-ERR110',
142
- pattern: /setTimeout\s*\(\s*(?:this\.\w+|function\s*\([^)]*\)\s*\{[^}]*this\.)/g,
143
- title: 'Potential "this" Binding Issue',
144
- description: 'Using "this" in setTimeout callback may not refer to expected context.',
145
- severity: 'medium',
146
- category: 'error',
147
- suggestion: 'Use arrow function or .bind(this).'
148
- },
149
- // Constructor without new
150
- {
151
- id: 'CS-ERR120',
152
- pattern: /(?:^|[^.])\b(?:Date|Array|Object|Map|Set|Promise)\s*\(\s*\)/g,
153
- title: 'Constructor Without "new"',
154
- description: 'Calling constructor without new may not work as expected.',
155
- severity: 'low',
156
- category: 'error',
157
- suggestion: 'Use "new" keyword with constructors.'
158
- },
159
- // Magic numbers
160
- {
161
- id: 'CS-ERR130',
162
- pattern: /(?:if|while|for|===?|!==?|[<>]=?)\s*\(?\s*(?:\d{3,}|\d+\.\d+)\s*(?!\s*(?:px|em|rem|%|vh|vw|s|ms))/g,
163
- title: 'Magic Number',
164
- description: 'Hardcoded number without context makes code hard to maintain.',
165
- severity: 'low',
166
- category: 'error',
167
- suggestion: 'Extract magic numbers into named constants.'
168
- },
169
- // Async in constructor
170
- {
171
- id: 'CS-ERR140',
172
- pattern: /constructor\s*\([^)]*\)\s*\{[^}]*await\s+/g,
173
- title: 'Await in Constructor',
174
- description: 'Constructors cannot be async - await will not work as expected.',
175
- severity: 'high',
176
- category: 'error',
177
- suggestion: 'Use a static factory method for async initialization.'
178
- }
179
- ];
1
+ // Error pattern analyzer - uses data-driven pattern system
2
+ // This file now delegates to the core analyzer with compiled patterns
3
+ import { analyzeErrorsWithPatterns } from './core.js';
4
+ // Main export - uses the data-driven pattern system
180
5
  export function analyzeErrors(code, filename) {
181
- const issues = [];
182
- const lines = code.split('\n');
183
- for (const patternDef of errorPatterns) {
184
- patternDef.pattern.lastIndex = 0;
185
- let match;
186
- while ((match = patternDef.pattern.exec(code)) !== null) {
187
- const beforeMatch = code.substring(0, match.index);
188
- const lineNumber = beforeMatch.split('\n').length;
189
- const lineContent = lines[lineNumber - 1] || '';
190
- // Build verification with actual values substituted
191
- let verification = patternDef.verification;
192
- if (verification) {
193
- verification = {
194
- ...verification,
195
- commands: verification.commands?.map(cmd => cmd.replace(/<filename>/g, filename))
196
- };
197
- }
198
- issues.push({
199
- id: patternDef.id,
200
- category: patternDef.category,
201
- severity: patternDef.severity,
202
- title: patternDef.title,
203
- description: patternDef.description,
204
- line: lineNumber,
205
- code: lineContent.trim(),
206
- suggestion: patternDef.suggestion,
207
- verification
208
- });
209
- if (!patternDef.pattern.global)
210
- break;
211
- }
212
- }
213
- return issues;
6
+ return analyzeErrorsWithPatterns(code, filename);
214
7
  }
@@ -1,216 +1,7 @@
1
- const placeholderPatterns = [
2
- // TODO/FIXME comments
3
- {
4
- id: 'CS-PH001',
5
- pattern: /\/\/\s*TODO(?::|\.|\s).*$/gim,
6
- title: 'TODO Comment Found',
7
- description: 'Incomplete work marker found in code.',
8
- severity: 'low',
9
- category: 'placeholder',
10
- suggestion: 'Complete or remove the TODO before shipping.'
11
- },
12
- {
13
- id: 'CS-PH002',
14
- pattern: /\/\/\s*FIXME(?::|\.|\s).*$/gim,
15
- title: 'FIXME Comment Found',
16
- description: 'Known issue marker found - this should be fixed.',
17
- severity: 'medium',
18
- category: 'placeholder',
19
- suggestion: 'Fix the issue or create a ticket to track it.'
20
- },
21
- {
22
- id: 'CS-PH003',
23
- pattern: /\/\/\s*HACK(?::|\.|\s).*$/gim,
24
- title: 'HACK Comment Found',
25
- description: 'Workaround marker found - technical debt.',
26
- severity: 'medium',
27
- category: 'placeholder',
28
- suggestion: 'Document why the hack exists and plan to remove it.'
29
- },
30
- {
31
- id: 'CS-PH004',
32
- pattern: /\/\/\s*XXX(?::|\.|\s).*$/gim,
33
- title: 'XXX Comment Found',
34
- description: 'Attention marker found - requires review.',
35
- severity: 'low',
36
- category: 'placeholder',
37
- suggestion: 'Address the flagged issue or remove the marker.'
38
- },
39
- // Lorem ipsum and dummy text
40
- {
41
- id: 'CS-PH010',
42
- pattern: /lorem\s+ipsum/gi,
43
- title: 'Lorem Ipsum Placeholder Text',
44
- description: 'Placeholder text found - replace with real content.',
45
- severity: 'medium',
46
- category: 'placeholder',
47
- suggestion: 'Replace with actual content before release.'
48
- },
49
- {
50
- id: 'CS-PH011',
51
- pattern: /['"`](?:foo|bar|baz|qux|test|dummy|sample|example|placeholder)['"`]/gi,
52
- title: 'Common Placeholder Value',
53
- description: 'Generic placeholder value detected.',
54
- severity: 'low',
55
- category: 'placeholder',
56
- suggestion: 'Replace with meaningful values.'
57
- },
58
- // Test/dummy data
59
- {
60
- id: 'CS-PH020',
61
- pattern: /['"`]test@(?:test|example|dummy|sample)\.[a-z]+['"`]/gi,
62
- title: 'Test Email Address',
63
- description: 'Placeholder email found - may not be intended for production.',
64
- severity: 'medium',
65
- category: 'placeholder',
66
- suggestion: 'Remove or replace with proper configuration.'
67
- },
68
- {
69
- id: 'CS-PH021',
70
- pattern: /['"`](?:123|1234|12345|123456|password|admin|root|test)['"`]/gi,
71
- title: 'Common Test Password/Value',
72
- description: 'Potentially insecure placeholder password or test value.',
73
- severity: 'high',
74
- category: 'placeholder',
75
- suggestion: 'Remove test credentials before deployment.'
76
- },
77
- {
78
- id: 'CS-PH022',
79
- pattern: /(?:localhost|127\.0\.0\.1):\d{4,5}/g,
80
- title: 'Localhost URL in Code',
81
- description: 'Hardcoded localhost URL may not work in production.',
82
- severity: 'medium',
83
- category: 'placeholder',
84
- suggestion: 'Use environment variables for URLs.'
85
- },
86
- {
87
- id: 'CS-PH023',
88
- pattern: /['"`](?:xxx|yyy|zzz|aaa|bbb|ccc)['"`]/gi,
89
- title: 'Placeholder String Pattern',
90
- description: 'Obvious placeholder pattern detected.',
91
- severity: 'low',
92
- category: 'placeholder',
93
- suggestion: 'Replace with actual values.'
94
- },
95
- // Fake/test phone numbers
96
- {
97
- id: 'CS-PH030',
98
- pattern: /['"`](?:\+1)?[\s-]?555[\s-]?\d{3}[\s-]?\d{4}['"`]/g,
99
- title: 'Test Phone Number (555)',
100
- description: 'The 555 prefix is reserved for fictional use.',
101
- severity: 'low',
102
- category: 'placeholder',
103
- suggestion: 'Use proper phone number handling or config.'
104
- },
105
- {
106
- id: 'CS-PH031',
107
- pattern: /['"`](?:000[-\s]?00[-\s]?0000|111[-\s]?11[-\s]?1111|123[-\s]?45[-\s]?6789)['"`]/g,
108
- title: 'Obviously Fake ID Number',
109
- description: 'Placeholder ID number pattern detected.',
110
- severity: 'medium',
111
- category: 'placeholder',
112
- suggestion: 'Remove test data before production.'
113
- },
114
- // Incomplete implementations
115
- {
116
- id: 'CS-PH040',
117
- pattern: /throw\s+new\s+Error\s*\(\s*['"`](?:not\s+implemented|todo|implement\s+me|coming\s+soon)['"`]\s*\)/gi,
118
- title: 'Not Implemented Error',
119
- description: 'Function explicitly marked as not implemented.',
120
- severity: 'high',
121
- category: 'placeholder',
122
- suggestion: 'Implement the function or remove the dead code.'
123
- },
124
- {
125
- id: 'CS-PH041',
126
- pattern: /(?:return|=)\s*['"`](?:TBD|TBA|N\/A|pending|placeholder)['"`]/gi,
127
- title: 'TBD/Placeholder Return Value',
128
- description: 'Code returns a placeholder instead of real value.',
129
- severity: 'medium',
130
- category: 'placeholder',
131
- suggestion: 'Implement actual logic or handle the case properly.'
132
- },
133
- // Debug/test code
134
- {
135
- id: 'CS-PH050',
136
- pattern: /console\.log\s*\(\s*['"`](?:debug|test|here|working|checkpoint|\d+)['"`]\s*\)/gi,
137
- title: 'Debug Console.log',
138
- description: 'Debug logging statement left in code.',
139
- severity: 'low',
140
- category: 'placeholder',
141
- suggestion: 'Remove debug statements or use a proper logger.'
142
- },
143
- {
144
- id: 'CS-PH051',
145
- pattern: /debugger\s*;/g,
146
- title: 'Debugger Statement',
147
- description: 'Debugger statement will pause execution in browser.',
148
- severity: 'medium',
149
- category: 'placeholder',
150
- suggestion: 'Remove debugger statements before committing.'
151
- },
152
- {
153
- id: 'CS-PH052',
154
- pattern: /alert\s*\(\s*['"`](?:test|debug|here|working)['"`]\s*\)/gi,
155
- title: 'Debug Alert',
156
- description: 'Debug alert left in code.',
157
- severity: 'medium',
158
- category: 'placeholder',
159
- suggestion: 'Remove debug alerts.'
160
- },
161
- // Commented out code blocks
162
- {
163
- id: 'CS-PH060',
164
- pattern: /\/\/\s*(?:const|let|var|function|class|if|for|while|return)\s+\w+/g,
165
- title: 'Commented Out Code',
166
- description: 'Code appears to be commented out rather than deleted.',
167
- severity: 'low',
168
- category: 'placeholder',
169
- suggestion: 'Remove dead code - use version control to recover if needed.'
170
- },
171
- // Hardcoded test IDs
172
- {
173
- id: 'CS-PH070',
174
- pattern: /['"`](?:test-id|test_id|testid|fake-id|temp-id)['"`]/gi,
175
- title: 'Test ID in Code',
176
- description: 'Hardcoded test ID found.',
177
- severity: 'medium',
178
- category: 'placeholder',
179
- suggestion: 'Use proper ID generation or configuration.'
180
- }
181
- ];
1
+ // Placeholder analyzer - uses data-driven pattern system
2
+ // This file now delegates to the core analyzer with compiled patterns
3
+ import { analyzePlaceholdersWithPatterns } from './core.js';
4
+ // Main export - uses the data-driven pattern system
182
5
  export function analyzePlaceholders(code, filename) {
183
- const issues = [];
184
- const lines = code.split('\n');
185
- for (const patternDef of placeholderPatterns) {
186
- patternDef.pattern.lastIndex = 0;
187
- let match;
188
- while ((match = patternDef.pattern.exec(code)) !== null) {
189
- const beforeMatch = code.substring(0, match.index);
190
- const lineNumber = beforeMatch.split('\n').length;
191
- const lineContent = lines[lineNumber - 1] || '';
192
- // Build verification with actual values substituted
193
- let verification = patternDef.verification;
194
- if (verification) {
195
- verification = {
196
- ...verification,
197
- commands: verification.commands?.map(cmd => cmd.replace(/<filename>/g, filename))
198
- };
199
- }
200
- issues.push({
201
- id: patternDef.id,
202
- category: patternDef.category,
203
- severity: patternDef.severity,
204
- title: patternDef.title,
205
- description: patternDef.description,
206
- line: lineNumber,
207
- code: lineContent.trim(),
208
- suggestion: patternDef.suggestion,
209
- verification
210
- });
211
- if (!patternDef.pattern.global)
212
- break;
213
- }
214
- }
215
- return issues;
6
+ return analyzePlaceholdersWithPatterns(code, filename);
216
7
  }
@@ -1,238 +1,7 @@
1
- const securityPatterns = [
2
- // Hardcoded secrets
3
- {
4
- id: 'CS-SEC001',
5
- pattern: /(?:api[_-]?key|apikey|secret|password|passwd|pwd|token|auth[_-]?token|access[_-]?token|private[_-]?key)\s*[:=]\s*['"`][^'"`]{8,}['"`]/gi,
6
- title: 'Hardcoded Secret Detected',
7
- description: 'Sensitive credentials appear to be hardcoded in the source code.',
8
- severity: 'critical',
9
- category: 'security',
10
- suggestion: 'Move secrets to environment variables or a secure vault.',
11
- verification: {
12
- status: 'needs_verification',
13
- assumption: 'The matched string appears to be a real secret, not a placeholder or test value',
14
- commands: [
15
- 'git log -p -S "<matched_value>" -- <filename>',
16
- 'grep -r "<matched_value>" .env* config/'
17
- ],
18
- instruction: 'Verify this is a real secret, not a placeholder like "your-api-key-here" or test data',
19
- confirmIf: 'Value looks like a real credential (high entropy, no placeholder words)',
20
- falsePositiveIf: 'Value contains words like "example", "test", "placeholder", "your-", "xxx", or is clearly dummy data'
21
- }
22
- },
23
- {
24
- id: 'CS-SEC002',
25
- pattern: /(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{36,}/g,
26
- title: 'GitHub Token Detected',
27
- description: 'A GitHub personal access token was found in the code.',
28
- severity: 'critical',
29
- category: 'security',
30
- suggestion: 'Remove the token immediately and rotate it in GitHub settings.',
31
- verification: {
32
- status: 'needs_verification',
33
- assumption: 'Token is real and may have been committed to git history',
34
- commands: [
35
- 'git log -p -S "<matched_value>" --all',
36
- 'git ls-files <filename>'
37
- ],
38
- instruction: 'Check if token was ever committed. If in history, it must be rotated even if removed now',
39
- confirmIf: 'Token pattern matches GitHub format (ghp_, gho_, etc.) and file is tracked',
40
- falsePositiveIf: 'Token is in a test file with obviously fake data or documentation example'
41
- }
42
- },
43
- {
44
- id: 'CS-SEC003',
45
- pattern: /sk-[A-Za-z0-9]{48,}/g,
46
- title: 'OpenAI API Key Detected',
47
- description: 'An OpenAI API key was found in the code.',
48
- severity: 'critical',
49
- category: 'security',
50
- suggestion: 'Remove the key and rotate it in your OpenAI dashboard.',
51
- verification: {
52
- status: 'needs_verification',
53
- assumption: 'Key is real and may have been committed to git history',
54
- commands: [
55
- 'git log -p -S "sk-" --all -- <filename>',
56
- 'git ls-files <filename>'
57
- ],
58
- instruction: 'Check if key was ever committed. If in history, it must be rotated',
59
- confirmIf: 'Key matches OpenAI format (sk- prefix, 48+ chars) and file is tracked',
60
- falsePositiveIf: 'Key is in documentation as example or clearly marked as fake'
61
- }
62
- },
63
- {
64
- id: 'CS-SEC004',
65
- pattern: /AKIA[0-9A-Z]{16}/g,
66
- title: 'AWS Access Key Detected',
67
- description: 'An AWS access key ID was found in the code.',
68
- severity: 'critical',
69
- category: 'security',
70
- suggestion: 'Remove and rotate the AWS credentials immediately.',
71
- verification: {
72
- status: 'needs_verification',
73
- assumption: 'Key is real and may have been committed to git history',
74
- commands: [
75
- 'git log -p -S "AKIA" --all -- <filename>',
76
- 'git ls-files <filename>'
77
- ],
78
- instruction: 'Check if key was ever committed. AWS keys in git history are compromised',
79
- confirmIf: 'Key matches AWS format (AKIA prefix, 16 chars) and file is tracked',
80
- falsePositiveIf: 'Key is in documentation or test fixtures with fake data'
81
- }
82
- },
83
- // SQL Injection
84
- {
85
- id: 'CS-SEC010',
86
- pattern: /(?:execute|query|raw)\s*\(\s*['"`].*?\$\{.*?\}.*?['"`]\s*\)/gi,
87
- title: 'Potential SQL Injection',
88
- description: 'String interpolation in SQL query may allow injection attacks.',
89
- severity: 'critical',
90
- category: 'security',
91
- suggestion: 'Use parameterized queries or prepared statements instead.'
92
- },
93
- {
94
- id: 'CS-SEC011',
95
- pattern: /(?:execute|query)\s*\(\s*['"`].*?\+.*?['"`]\s*\)/gi,
96
- title: 'SQL Query String Concatenation',
97
- description: 'Concatenating strings in SQL queries is vulnerable to injection.',
98
- severity: 'high',
99
- category: 'security',
100
- suggestion: 'Use parameterized queries with placeholders.'
101
- },
102
- // XSS
103
- {
104
- id: 'CS-SEC020',
105
- pattern: /innerHTML\s*=\s*(?!['"`]<)/g,
106
- title: 'Potential XSS via innerHTML',
107
- description: 'Setting innerHTML with dynamic content can lead to XSS.',
108
- severity: 'high',
109
- category: 'security',
110
- suggestion: 'Use textContent or sanitize HTML before insertion.'
111
- },
112
- {
113
- id: 'CS-SEC021',
114
- pattern: /dangerouslySetInnerHTML/g,
115
- title: 'React dangerouslySetInnerHTML Usage',
116
- description: 'Using dangerouslySetInnerHTML can expose the app to XSS.',
117
- severity: 'medium',
118
- category: 'security',
119
- suggestion: 'Ensure content is properly sanitized before rendering.'
120
- },
121
- // Insecure practices
122
- {
123
- id: 'CS-SEC030',
124
- pattern: /eval\s*\(/g,
125
- title: 'eval() Usage Detected',
126
- description: 'eval() can execute arbitrary code and is a security risk.',
127
- severity: 'high',
128
- category: 'security',
129
- suggestion: 'Avoid eval(). Use safer alternatives like JSON.parse().'
130
- },
131
- {
132
- id: 'CS-SEC031',
133
- pattern: /new\s+Function\s*\(/g,
134
- title: 'Dynamic Function Constructor',
135
- description: 'Creating functions from strings is similar to eval().',
136
- severity: 'high',
137
- category: 'security',
138
- suggestion: 'Avoid dynamic function creation from user input.'
139
- },
140
- {
141
- id: 'CS-SEC032',
142
- pattern: /document\.write\s*\(/g,
143
- title: 'document.write() Usage',
144
- description: 'document.write() can overwrite the document and enable XSS.',
145
- severity: 'medium',
146
- category: 'security',
147
- suggestion: 'Use DOM manipulation methods instead.'
148
- },
149
- // Crypto issues
150
- {
151
- id: 'CS-SEC040',
152
- pattern: /(?:md5|sha1)\s*\(/gi,
153
- title: 'Weak Hash Algorithm',
154
- description: 'MD5 and SHA1 are cryptographically broken.',
155
- severity: 'high',
156
- category: 'security',
157
- suggestion: 'Use SHA-256 or bcrypt for password hashing.'
158
- },
159
- {
160
- id: 'CS-SEC041',
161
- pattern: /Math\.random\s*\(\)/g,
162
- title: 'Insecure Random for Security',
163
- description: 'Math.random() is not cryptographically secure.',
164
- severity: 'medium',
165
- category: 'security',
166
- suggestion: 'Use crypto.randomBytes() or crypto.getRandomValues().'
167
- },
168
- // Network
169
- {
170
- id: 'CS-SEC050',
171
- pattern: /http:\/\/(?!localhost|127\.0\.0\.1)/g,
172
- title: 'Insecure HTTP URL',
173
- description: 'Using HTTP instead of HTTPS exposes data in transit.',
174
- severity: 'medium',
175
- category: 'security',
176
- suggestion: 'Use HTTPS for all external URLs.'
177
- },
178
- {
179
- id: 'CS-SEC051',
180
- pattern: /rejectUnauthorized\s*:\s*false/g,
181
- title: 'SSL Certificate Validation Disabled',
182
- description: 'Disabling certificate validation enables MITM attacks.',
183
- severity: 'critical',
184
- category: 'security',
185
- suggestion: 'Never disable SSL certificate validation in production.'
186
- },
187
- // CORS
188
- {
189
- id: 'CS-SEC060',
190
- pattern: /Access-Control-Allow-Origin['":\s]+\*/g,
191
- title: 'Wildcard CORS Origin',
192
- description: 'Allowing all origins can expose the API to unauthorized access.',
193
- severity: 'medium',
194
- category: 'security',
195
- suggestion: 'Specify allowed origins explicitly.'
196
- }
197
- ];
1
+ // Security analyzer - uses data-driven pattern system
2
+ // This file now delegates to the core analyzer with compiled patterns
3
+ import { analyzeSecurityWithPatterns } from './core.js';
4
+ // Main export - uses the data-driven pattern system
198
5
  export function analyzeSecurityIssues(code, filename) {
199
- const issues = [];
200
- const lines = code.split('\n');
201
- for (const patternDef of securityPatterns) {
202
- // Reset regex state
203
- patternDef.pattern.lastIndex = 0;
204
- let match;
205
- while ((match = patternDef.pattern.exec(code)) !== null) {
206
- // Find line number
207
- const beforeMatch = code.substring(0, match.index);
208
- const lineNumber = beforeMatch.split('\n').length;
209
- const lineContent = lines[lineNumber - 1] || '';
210
- const matchedValue = match[0];
211
- // Build verification with actual values substituted
212
- let verification = patternDef.verification;
213
- if (verification) {
214
- verification = {
215
- ...verification,
216
- commands: verification.commands?.map(cmd => cmd
217
- .replace(/<matched_value>/g, matchedValue.substring(0, 20) + '...')
218
- .replace(/<filename>/g, filename))
219
- };
220
- }
221
- issues.push({
222
- id: patternDef.id,
223
- category: patternDef.category,
224
- severity: patternDef.severity,
225
- title: patternDef.title,
226
- description: patternDef.description,
227
- line: lineNumber,
228
- code: lineContent.trim(),
229
- suggestion: patternDef.suggestion,
230
- verification
231
- });
232
- // Prevent infinite loops for patterns without global flag
233
- if (!patternDef.pattern.global)
234
- break;
235
- }
236
- }
237
- return issues;
6
+ return analyzeSecurityWithPatterns(code, filename);
238
7
  }