codeslick-cli 1.1.6 → 1.2.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 (90) hide show
  1. package/__tests__/local-scanner.test.ts +5 -0
  2. package/dist/packages/cli/src/commands/scan.d.ts.map +1 -1
  3. package/dist/packages/cli/src/commands/scan.js +3 -1
  4. package/dist/packages/cli/src/commands/scan.js.map +1 -1
  5. package/dist/packages/cli/src/config/config-loader.d.ts +2 -2
  6. package/dist/packages/cli/src/config/config-loader.d.ts.map +1 -1
  7. package/dist/packages/cli/src/config/config-loader.js +2 -2
  8. package/dist/packages/cli/src/config/config-loader.js.map +1 -1
  9. package/dist/packages/cli/src/scanner/local-scanner.d.ts +2 -2
  10. package/dist/packages/cli/src/scanner/local-scanner.d.ts.map +1 -1
  11. package/dist/packages/cli/src/scanner/local-scanner.js +10 -1
  12. package/dist/packages/cli/src/scanner/local-scanner.js.map +1 -1
  13. package/dist/src/lib/analyzers/go/quality-checks/code-quality.d.ts +20 -0
  14. package/dist/src/lib/analyzers/go/quality-checks/code-quality.d.ts.map +1 -0
  15. package/dist/src/lib/analyzers/go/quality-checks/code-quality.js +211 -0
  16. package/dist/src/lib/analyzers/go/quality-checks/code-quality.js.map +1 -0
  17. package/dist/src/lib/analyzers/go/security-checks/access-control.d.ts +20 -0
  18. package/dist/src/lib/analyzers/go/security-checks/access-control.d.ts.map +1 -0
  19. package/dist/src/lib/analyzers/go/security-checks/access-control.js +201 -0
  20. package/dist/src/lib/analyzers/go/security-checks/access-control.js.map +1 -0
  21. package/dist/src/lib/analyzers/go/security-checks/ai-generated-code.d.ts +25 -0
  22. package/dist/src/lib/analyzers/go/security-checks/ai-generated-code.d.ts.map +1 -0
  23. package/dist/src/lib/analyzers/go/security-checks/ai-generated-code.js +545 -0
  24. package/dist/src/lib/analyzers/go/security-checks/ai-generated-code.js.map +1 -0
  25. package/dist/src/lib/analyzers/go/security-checks/concurrency-safety.d.ts +23 -0
  26. package/dist/src/lib/analyzers/go/security-checks/concurrency-safety.d.ts.map +1 -0
  27. package/dist/src/lib/analyzers/go/security-checks/concurrency-safety.js +321 -0
  28. package/dist/src/lib/analyzers/go/security-checks/concurrency-safety.js.map +1 -0
  29. package/dist/src/lib/analyzers/go/security-checks/credentials-crypto.d.ts +22 -0
  30. package/dist/src/lib/analyzers/go/security-checks/credentials-crypto.d.ts.map +1 -0
  31. package/dist/src/lib/analyzers/go/security-checks/credentials-crypto.js +267 -0
  32. package/dist/src/lib/analyzers/go/security-checks/credentials-crypto.js.map +1 -0
  33. package/dist/src/lib/analyzers/go/security-checks/deserialization.d.ts +19 -0
  34. package/dist/src/lib/analyzers/go/security-checks/deserialization.d.ts.map +1 -0
  35. package/dist/src/lib/analyzers/go/security-checks/deserialization.js +210 -0
  36. package/dist/src/lib/analyzers/go/security-checks/deserialization.js.map +1 -0
  37. package/dist/src/lib/analyzers/go/security-checks/error-handling.d.ts +19 -0
  38. package/dist/src/lib/analyzers/go/security-checks/error-handling.d.ts.map +1 -0
  39. package/dist/src/lib/analyzers/go/security-checks/error-handling.js +192 -0
  40. package/dist/src/lib/analyzers/go/security-checks/error-handling.js.map +1 -0
  41. package/dist/src/lib/analyzers/go/security-checks/injection-attacks.d.ts +24 -0
  42. package/dist/src/lib/analyzers/go/security-checks/injection-attacks.d.ts.map +1 -0
  43. package/dist/src/lib/analyzers/go/security-checks/injection-attacks.js +401 -0
  44. package/dist/src/lib/analyzers/go/security-checks/injection-attacks.js.map +1 -0
  45. package/dist/src/lib/analyzers/go/security-checks/ssrf-detection.d.ts +19 -0
  46. package/dist/src/lib/analyzers/go/security-checks/ssrf-detection.d.ts.map +1 -0
  47. package/dist/src/lib/analyzers/go/security-checks/ssrf-detection.js +252 -0
  48. package/dist/src/lib/analyzers/go/security-checks/ssrf-detection.js.map +1 -0
  49. package/dist/src/lib/analyzers/go/security-checks/tls-configuration.d.ts +19 -0
  50. package/dist/src/lib/analyzers/go/security-checks/tls-configuration.d.ts.map +1 -0
  51. package/dist/src/lib/analyzers/go/security-checks/tls-configuration.js +112 -0
  52. package/dist/src/lib/analyzers/go/security-checks/tls-configuration.js.map +1 -0
  53. package/dist/src/lib/analyzers/go/security-checks/web-security.d.ts +22 -0
  54. package/dist/src/lib/analyzers/go/security-checks/web-security.d.ts.map +1 -0
  55. package/dist/src/lib/analyzers/go/security-checks/web-security.js +244 -0
  56. package/dist/src/lib/analyzers/go/security-checks/web-security.js.map +1 -0
  57. package/dist/src/lib/analyzers/go/utils/createVulnerability.d.ts +58 -0
  58. package/dist/src/lib/analyzers/go/utils/createVulnerability.d.ts.map +1 -0
  59. package/dist/src/lib/analyzers/go/utils/createVulnerability.js +71 -0
  60. package/dist/src/lib/analyzers/go/utils/createVulnerability.js.map +1 -0
  61. package/dist/src/lib/analyzers/go-analyzer.d.ts +48 -0
  62. package/dist/src/lib/analyzers/go-analyzer.d.ts.map +1 -0
  63. package/dist/src/lib/analyzers/go-analyzer.js +233 -0
  64. package/dist/src/lib/analyzers/go-analyzer.js.map +1 -0
  65. package/dist/src/lib/analyzers/helpers/ai-code-detection-utils.d.ts.map +1 -1
  66. package/dist/src/lib/analyzers/helpers/ai-code-detection-utils.js +1 -0
  67. package/dist/src/lib/analyzers/helpers/ai-code-detection-utils.js.map +1 -1
  68. package/dist/src/lib/analyzers/python/security-checks/injection-attacks.d.ts +5 -3
  69. package/dist/src/lib/analyzers/python/security-checks/injection-attacks.d.ts.map +1 -1
  70. package/dist/src/lib/analyzers/python/security-checks/injection-attacks.js +23 -5
  71. package/dist/src/lib/analyzers/python/security-checks/injection-attacks.js.map +1 -1
  72. package/dist/src/lib/analyzers/python-analyzer.d.ts.map +1 -1
  73. package/dist/src/lib/analyzers/python-analyzer.js +17 -1
  74. package/dist/src/lib/analyzers/python-analyzer.js.map +1 -1
  75. package/dist/src/lib/analyzers/secrets/secrets-analyzer.d.ts +1 -1
  76. package/dist/src/lib/analyzers/secrets/secrets-analyzer.d.ts.map +1 -1
  77. package/dist/src/lib/analyzers/secrets/secrets-analyzer.js.map +1 -1
  78. package/dist/src/lib/security/compliance-mapping.d.ts.map +1 -1
  79. package/dist/src/lib/security/compliance-mapping.js +403 -0
  80. package/dist/src/lib/security/compliance-mapping.js.map +1 -1
  81. package/dist/src/lib/security/severity-scoring.d.ts.map +1 -1
  82. package/dist/src/lib/security/severity-scoring.js +169 -0
  83. package/dist/src/lib/security/severity-scoring.js.map +1 -1
  84. package/dist/src/lib/types/index.d.ts +2 -2
  85. package/dist/src/lib/types/index.d.ts.map +1 -1
  86. package/example3.go +23 -0
  87. package/package.json +1 -1
  88. package/src/commands/scan.ts +3 -1
  89. package/src/config/config-loader.ts +3 -3
  90. package/src/scanner/local-scanner.ts +13 -2
@@ -0,0 +1,321 @@
1
+ "use strict";
2
+ /**
3
+ * Go Concurrency Safety Security Checks
4
+ * OWASP A04:2025 - Insecure Design
5
+ *
6
+ * Detects concurrency-related vulnerabilities in Go code including race conditions
7
+ * and goroutine leaks.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.checkConcurrencySafety = checkConcurrencySafety;
11
+ const createVulnerability_1 = require("../utils/createVulnerability");
12
+ /**
13
+ * Checks for concurrency safety issues
14
+ *
15
+ * Covers:
16
+ * - Check #1: Race conditions (unsynchronized variable access in concurrent contexts) (HIGH)
17
+ * - Map access without mutex protection
18
+ * - Slice modifications without synchronization
19
+ * - Simple variable operations (counter++, assignments) without mutex/atomic
20
+ * - Check #2: Goroutine leaks (unclosed channels) (MEDIUM)
21
+ *
22
+ * @param lines - Array of code lines
23
+ * @returns Array of security vulnerabilities found
24
+ */
25
+ function checkConcurrencySafety(lines) {
26
+ const vulnerabilities = [];
27
+ let inMultiLineComment = false;
28
+ // First pass: Track goroutines, channels, maps, and slices
29
+ const fileContent = lines.join('\n');
30
+ const hasGoroutines = /go\s+\w+\s*\(|go\s+func\s*\(/i.test(fileContent);
31
+ const hasChannels = /make\s*\(\s*chan\s+/i.test(fileContent);
32
+ // Track map and slice declarations
33
+ const mapVars = new Set();
34
+ const sliceVars = new Set();
35
+ const channelVars = new Set();
36
+ const mutexVars = new Set();
37
+ // First pass: Collect variable declarations
38
+ lines.forEach((line, index) => {
39
+ const trimmed = line.trim();
40
+ // Track map declarations
41
+ const mapMatch = trimmed.match(/(\w+)\s*(?::=|=)\s*make\s*\(\s*map\s*\[/i);
42
+ if (mapMatch) {
43
+ mapVars.add(mapMatch[1]);
44
+ }
45
+ // Track slice declarations (var name []type, name := []type, name := make([]type))
46
+ const sliceMatch = trimmed.match(/(?:var\s+)?(\w+)\s*(?::=|=|\s)\s*(?:make\s*\(\s*)?(\[\])/i);
47
+ if (sliceMatch && !trimmed.includes('map[')) {
48
+ sliceVars.add(sliceMatch[1]);
49
+ }
50
+ // Track channel declarations
51
+ const chanMatch = trimmed.match(/(\w+)\s*(?::=|=)\s*make\s*\(\s*chan\s+/i);
52
+ if (chanMatch) {
53
+ channelVars.add(chanMatch[1]);
54
+ }
55
+ // Track mutex declarations
56
+ const mutexMatch = trimmed.match(/(\w+)\s+(?:sync\.)?(?:Mutex|RWMutex)/i);
57
+ if (mutexMatch) {
58
+ mutexVars.add(mutexMatch[1]);
59
+ }
60
+ });
61
+ // Second pass: Check for unsafe concurrent access
62
+ lines.forEach((line, index) => {
63
+ const lineNumber = index + 1;
64
+ const trimmed = line.trim();
65
+ // Track multi-line comments (/* ... */)
66
+ if (trimmed.includes('/*')) {
67
+ inMultiLineComment = true;
68
+ }
69
+ if (trimmed.includes('*/')) {
70
+ inMultiLineComment = false;
71
+ return;
72
+ }
73
+ // Skip comments and empty lines
74
+ if (!trimmed || inMultiLineComment || trimmed.startsWith('//')) {
75
+ return;
76
+ }
77
+ // =============================================================================
78
+ // Check #1: Race Conditions (Unsynchronized Map/Slice Access)
79
+ // =============================================================================
80
+ // CVSS 7.0 - HIGH
81
+ // Detects concurrent access to maps/slices without synchronization
82
+ if (hasGoroutines) {
83
+ // Check for map access without mutex protection
84
+ for (const mapVar of mapVars) {
85
+ const hasMapAccess = new RegExp(`${mapVar}\\s*\\[|${mapVar}\\s*=`, 'i').test(trimmed);
86
+ if (hasMapAccess) {
87
+ // Look for mutex protection in surrounding ±10 lines
88
+ let hasMutexProtection = false;
89
+ const startLine = Math.max(0, index - 10);
90
+ const endLine = Math.min(lines.length, index + 10);
91
+ for (let i = startLine; i < endLine; i++) {
92
+ const contextLine = lines[i].trim();
93
+ if (/\.Lock\(\)|\.RLock\(\)|\.Unlock\(\)|\.RUnlock\(\)|sync\.Map/i.test(contextLine)) {
94
+ hasMutexProtection = true;
95
+ break;
96
+ }
97
+ }
98
+ // Also check if goroutine is in the context
99
+ let hasGoroutineInContext = false;
100
+ for (let i = startLine; i < endLine; i++) {
101
+ if (/go\s+func|go\s+\w+\s*\(/i.test(lines[i])) {
102
+ hasGoroutineInContext = true;
103
+ break;
104
+ }
105
+ }
106
+ if (!hasMutexProtection && hasGoroutineInContext) {
107
+ vulnerabilities.push((0, createVulnerability_1.createGoSecurityVulnerability)({
108
+ category: 'go-race-condition',
109
+ severity: 'high',
110
+ confidence: 'medium',
111
+ message: `Potential race condition: Map '${mapVar}' accessed without synchronization in concurrent context`,
112
+ line: lineNumber,
113
+ suggestion: 'Use sync.Mutex or sync.RWMutex to protect concurrent map access, or use sync.Map',
114
+ owasp: 'A04:2025 - Insecure Design',
115
+ cwe: 'CWE-362',
116
+ pciDss: 'PCI DSS 6.5.6',
117
+ remediation: {
118
+ explanation: 'Concurrent map access in Go causes runtime panics and data races. Use sync.Mutex/sync.RWMutex for protection, or use sync.Map for concurrent-safe operations.',
119
+ before: `// UNSAFE\nvar cache = make(map[string]string)\ngo func() {\n cache["key"] = "value" // Race condition!\n}()\nvalue := cache["key"]`,
120
+ after: `// SAFE\nvar (\n cache = make(map[string]string)\n mu sync.RWMutex\n)\ngo func() {\n mu.Lock()\n cache["key"] = "value"\n mu.Unlock()\n}()\nmu.RLock()\nvalue := cache["key"]\nmu.RUnlock()`
121
+ },
122
+ attackVector: {
123
+ description: 'Race conditions in concurrent map access can cause data corruption, inconsistent state, or runtime panics (fatal errors). Attackers can exploit race conditions to bypass security checks or corrupt application state.',
124
+ exploitExample: `// Vulnerable:\nvar sessionCache = make(map[string]*Session)\ngo cleanupExpiredSessions(sessionCache)\n// Attacker triggers concurrent access\nif session, ok := sessionCache[token]; ok {\n // Race: session might be deleted by cleanup goroutine\n if session.IsAdmin { // Panic or wrong data!\n grantAdminAccess()\n }\n}`,
125
+ realWorldImpact: [
126
+ 'Application crashes (runtime panic on concurrent map access)',
127
+ 'Data corruption and inconsistent state',
128
+ 'Authentication/authorization bypass via race conditions',
129
+ 'Security check bypasses (TOCTOU vulnerabilities)',
130
+ 'Difficult to reproduce bugs in production'
131
+ ]
132
+ }
133
+ }));
134
+ break; // Only report once per map variable
135
+ }
136
+ }
137
+ }
138
+ // Check for slice access without synchronization
139
+ for (const sliceVar of sliceVars) {
140
+ const hasSliceWrite = new RegExp(`${sliceVar}\\s*=\\s*append\\(|${sliceVar}\\[\\d+\\]\\s*=`, 'i').test(trimmed);
141
+ if (hasSliceWrite) {
142
+ // Look for mutex protection in surrounding ±10 lines
143
+ let hasMutexProtection = false;
144
+ const startLine = Math.max(0, index - 10);
145
+ const endLine = Math.min(lines.length, index + 10);
146
+ for (let i = startLine; i < endLine; i++) {
147
+ const contextLine = lines[i].trim();
148
+ if (/\.Lock\(\)|\.RLock\(\)|\.Unlock\(\)|\.RUnlock\(\)/i.test(contextLine)) {
149
+ hasMutexProtection = true;
150
+ break;
151
+ }
152
+ }
153
+ // Check for goroutine context
154
+ let hasGoroutineInContext = false;
155
+ for (let i = startLine; i < endLine; i++) {
156
+ if (/go\s+func|go\s+\w+\s*\(/i.test(lines[i])) {
157
+ hasGoroutineInContext = true;
158
+ break;
159
+ }
160
+ }
161
+ if (!hasMutexProtection && hasGoroutineInContext) {
162
+ vulnerabilities.push((0, createVulnerability_1.createGoSecurityVulnerability)({
163
+ category: 'go-race-condition',
164
+ severity: 'high',
165
+ confidence: 'medium',
166
+ message: `Potential race condition: Slice '${sliceVar}' modified without synchronization in concurrent context`,
167
+ line: lineNumber,
168
+ suggestion: 'Use sync.Mutex or sync.RWMutex to protect concurrent slice modifications',
169
+ owasp: 'A04:2025 - Insecure Design',
170
+ cwe: 'CWE-362',
171
+ pciDss: 'PCI DSS 6.5.6',
172
+ remediation: {
173
+ explanation: 'Concurrent slice modifications cause data races. While slices don\'t panic like maps, they can corrupt data. Use sync.Mutex to protect writes.',
174
+ before: `// UNSAFE\nvar items []string\ngo func() {\n items = append(items, "value") // Race!\n}()`,
175
+ after: `// SAFE\nvar (\n items []string\n mu sync.Mutex\n)\ngo func() {\n mu.Lock()\n items = append(items, "value")\n mu.Unlock()\n}()`
176
+ },
177
+ attackVector: {
178
+ description: 'Concurrent slice modifications cause data races that can corrupt memory, lose data, or cause inconsistent state.',
179
+ exploitExample: `// Multiple goroutines appending:\nfor i := 0; i < 10; i++ {\n go func(val int) {\n results = append(results, val) // Race!\n }(i)\n}\n// Result: Lost updates, corrupted data`,
180
+ realWorldImpact: [
181
+ 'Data loss (lost append operations)',
182
+ 'Memory corruption',
183
+ 'Inconsistent application state',
184
+ 'Difficult to debug intermittent failures'
185
+ ]
186
+ }
187
+ }));
188
+ break; // Only report once per slice variable
189
+ }
190
+ }
191
+ }
192
+ // Check for simple variable race conditions (int, string, bool, etc.)
193
+ // Detect patterns like: counter++, counter--, counter += value, counter = value
194
+ const simpleVarPattern = /(\w+)\s*(?:\+\+|--|[\+\-\*\/]=|=(?!=))/;
195
+ const match = trimmed.match(simpleVarPattern);
196
+ if (match) {
197
+ const varName = match[1];
198
+ // Skip if it's a struct field assignment (contains .)
199
+ // Skip if it's a declaration (var, const, :=)
200
+ if (!trimmed.includes('.') && !trimmed.includes('var ') && !trimmed.includes('const ') && !trimmed.includes(':=')) {
201
+ // Check for goroutine context
202
+ let hasGoroutineInContext = false;
203
+ const startLine = Math.max(0, index - 10);
204
+ const endLine = Math.min(lines.length, index + 10);
205
+ for (let i = startLine; i < endLine; i++) {
206
+ if (/go\s+func|go\s+\w+\s*\(/i.test(lines[i])) {
207
+ hasGoroutineInContext = true;
208
+ break;
209
+ }
210
+ }
211
+ // Check for mutex protection
212
+ let hasMutexProtection = false;
213
+ for (let i = startLine; i < endLine; i++) {
214
+ const contextLine = lines[i].trim();
215
+ if (/\.Lock\(\)|\.RLock\(\)|\.Unlock\(\)|\.RUnlock\(\)|sync\.Mutex|sync\.RWMutex/i.test(contextLine)) {
216
+ hasMutexProtection = true;
217
+ break;
218
+ }
219
+ }
220
+ if (hasGoroutineInContext && !hasMutexProtection) {
221
+ vulnerabilities.push((0, createVulnerability_1.createGoSecurityVulnerability)({
222
+ category: 'go-race-condition',
223
+ severity: 'high',
224
+ confidence: 'medium',
225
+ message: `Potential race condition: Variable '${varName}' accessed/modified without synchronization in concurrent context`,
226
+ line: lineNumber,
227
+ suggestion: 'Use sync.Mutex, sync.RWMutex, or atomic operations (sync/atomic package) to protect concurrent access',
228
+ owasp: 'A04:2025 - Insecure Design',
229
+ cwe: 'CWE-362',
230
+ pciDss: 'PCI DSS 6.5.6',
231
+ remediation: {
232
+ explanation: 'Concurrent access to shared variables without synchronization causes data races. Use sync.Mutex for simple protection, or atomic operations for better performance on counters.',
233
+ before: `// UNSAFE\nvar counter int\ngo func() {\n for i := 0; i < 1000; i++ {\n counter++ // Race condition!\n }\n}()\ncounter++`,
234
+ after: `// SAFE Option 1: Using Mutex\nvar (\n counter int\n mu sync.Mutex\n)\ngo func() {\n for i := 0; i < 1000; i++ {\n mu.Lock()\n counter++\n mu.Unlock()\n }\n}()\nmu.Lock()\ncounter++\nmu.Unlock()\n\n// SAFE Option 2: Using atomic (better for counters)\nvar counter int64\ngo func() {\n for i := 0; i < 1000; i++ {\n atomic.AddInt64(&counter, 1)\n }\n}()\natomic.AddInt64(&counter, 1)`
235
+ },
236
+ attackVector: {
237
+ description: 'Race conditions on shared variables can cause data corruption, lost updates, and unpredictable behavior. In security contexts, this can lead to authorization bypasses or state corruption.',
238
+ exploitExample: `// Vulnerable:\nvar loginAttempts int\ngo func() {\n loginAttempts = 0 // Reset counter\n}()\n// Race: Check might see old value\nif loginAttempts < 3 {\n // Attacker can bypass rate limit via race condition\n allowLogin()\n}`,
239
+ realWorldImpact: [
240
+ 'Data corruption and lost updates',
241
+ 'Authentication/authorization bypasses',
242
+ 'Rate limiting failures',
243
+ 'Inconsistent application state',
244
+ 'Security check bypasses (TOCTOU vulnerabilities)'
245
+ ]
246
+ }
247
+ }));
248
+ }
249
+ }
250
+ }
251
+ }
252
+ // =============================================================================
253
+ // Check #2: Goroutine Leaks (Unclosed Channels)
254
+ // =============================================================================
255
+ // CVSS 4.0 - MEDIUM
256
+ // Detects channels that are created but never closed, causing goroutine leaks
257
+ if (hasChannels) {
258
+ for (const chanVar of channelVars) {
259
+ // Check if this channel is ever closed in the file
260
+ const channelClosedPattern = new RegExp(`close\\s*\\(\\s*${chanVar}\\s*\\)`, 'i');
261
+ const isChannelClosed = channelClosedPattern.test(fileContent);
262
+ // Check if channel is used in a goroutine context
263
+ let channelUsedInGoroutine = false;
264
+ let goroutineStartLine = -1;
265
+ for (let i = 0; i < lines.length; i++) {
266
+ const contextLine = lines[i].trim();
267
+ // Track goroutine start
268
+ if (/go\s+func|go\s+\w+\s*\(/i.test(contextLine)) {
269
+ goroutineStartLine = i;
270
+ }
271
+ // Check if channel is used after goroutine start
272
+ const chanUsagePattern = new RegExp(`${chanVar}\\s*<-|<-\\s*${chanVar}`, 'i');
273
+ if (goroutineStartLine >= 0 && chanUsagePattern.test(contextLine)) {
274
+ channelUsedInGoroutine = true;
275
+ break;
276
+ }
277
+ }
278
+ // Report if channel is never closed and used in goroutine
279
+ if (!isChannelClosed && channelUsedInGoroutine) {
280
+ // Find the line where the channel is declared
281
+ for (let i = 0; i < lines.length; i++) {
282
+ const declLine = lines[i].trim();
283
+ const declMatch = declLine.match(new RegExp(`${chanVar}\\s*(?::=|=)\\s*make\\s*\\(\\s*chan`, 'i'));
284
+ if (declMatch) {
285
+ vulnerabilities.push((0, createVulnerability_1.createGoSecurityVulnerability)({
286
+ category: 'go-goroutine-leak',
287
+ severity: 'medium',
288
+ confidence: 'medium',
289
+ message: `Potential goroutine leak: Channel '${chanVar}' is never closed`,
290
+ line: i + 1,
291
+ suggestion: 'Close the channel with close() when done to prevent goroutine leaks',
292
+ owasp: 'A04:2025 - Insecure Design',
293
+ cwe: 'CWE-404',
294
+ pciDss: 'PCI DSS 6.5.6',
295
+ remediation: {
296
+ explanation: 'Goroutines waiting on channels that are never closed will leak memory and resources. Always close channels when done, typically using defer close() in the sender.',
297
+ before: `func processItems() {\n ch := make(chan int)\n go func() {\n for item := range ch { // Blocks forever if ch not closed\n process(item)\n }\n }()\n ch <- 1\n}`,
298
+ after: `func processItems() {\n ch := make(chan int)\n go func() {\n for item := range ch {\n process(item)\n }\n }()\n ch <- 1\n close(ch) // Prevents goroutine leak\n}`
299
+ },
300
+ attackVector: {
301
+ description: 'Unclosed channels cause goroutine leaks. Each leaked goroutine consumes memory (~2KB stack). Over time, this leads to memory exhaustion and application crashes.',
302
+ exploitExample: `// Attacker triggers many requests:\nfor i := 0; i < 100000; i++ {\n ch := make(chan Result)\n go fetchData(ch)\n result := <-ch\n // Channel never closed - goroutine leaks!\n}\n// Result: 100K leaked goroutines = 200MB+ wasted memory`,
303
+ realWorldImpact: [
304
+ 'Memory leaks and eventual OOM crashes',
305
+ 'Resource exhaustion (file descriptors, connections)',
306
+ 'Performance degradation over time',
307
+ 'Denial of Service through resource exhaustion',
308
+ 'Increased infrastructure costs'
309
+ ]
310
+ }
311
+ }));
312
+ break; // Only report once per channel
313
+ }
314
+ }
315
+ }
316
+ }
317
+ }
318
+ });
319
+ return vulnerabilities;
320
+ }
321
+ //# sourceMappingURL=concurrency-safety.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency-safety.js","sourceRoot":"","sources":["../../../../../../../../src/lib/analyzers/go/security-checks/concurrency-safety.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Go Credentials and Cryptography Security Checks
3
+ * OWASP A07:2025 - Authentication Failures, A02:2025 - Cryptographic Failures
4
+ *
5
+ * Detects hardcoded credentials, weak cryptographic practices, and insecure
6
+ * random number generation in Go code.
7
+ */
8
+ import { SecurityVulnerability } from '../../types';
9
+ /**
10
+ * Checks for credential exposure and cryptographic weaknesses
11
+ *
12
+ * Covers:
13
+ * - Check #1: Hardcoded API keys/tokens (CRITICAL)
14
+ * - Check #2: Hardcoded passwords/secrets (CRITICAL)
15
+ * - Check #3: Weak password hashing with MD5/SHA1 (HIGH)
16
+ * - Check #4: Weak random number generation with math/rand (HIGH)
17
+ *
18
+ * @param lines - Array of code lines
19
+ * @returns Array of security vulnerabilities found
20
+ */
21
+ export declare function checkCredentialsAndCrypto(lines: string[]): SecurityVulnerability[];
22
+ //# sourceMappingURL=credentials-crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials-crypto.d.ts","sourceRoot":"","sources":["../../../../../../../../src/lib/analyzers/go/security-checks/credentials-crypto.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGpD;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,qBAAqB,EAAE,CA+SlF"}
@@ -0,0 +1,267 @@
1
+ "use strict";
2
+ /**
3
+ * Go Credentials and Cryptography Security Checks
4
+ * OWASP A07:2025 - Authentication Failures, A02:2025 - Cryptographic Failures
5
+ *
6
+ * Detects hardcoded credentials, weak cryptographic practices, and insecure
7
+ * random number generation in Go code.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.checkCredentialsAndCrypto = checkCredentialsAndCrypto;
11
+ const createVulnerability_1 = require("../utils/createVulnerability");
12
+ /**
13
+ * Checks for credential exposure and cryptographic weaknesses
14
+ *
15
+ * Covers:
16
+ * - Check #1: Hardcoded API keys/tokens (CRITICAL)
17
+ * - Check #2: Hardcoded passwords/secrets (CRITICAL)
18
+ * - Check #3: Weak password hashing with MD5/SHA1 (HIGH)
19
+ * - Check #4: Weak random number generation with math/rand (HIGH)
20
+ *
21
+ * @param lines - Array of code lines
22
+ * @returns Array of security vulnerabilities found
23
+ */
24
+ function checkCredentialsAndCrypto(lines) {
25
+ const vulnerabilities = [];
26
+ let inMultiLineComment = false;
27
+ // First pass: Check if file imports crypto/rand or math/rand
28
+ const fileContent = lines.join('\n');
29
+ const hasCryptoRandImport = /"crypto\/rand"/.test(fileContent);
30
+ const hasMathRandImport = /"math\/rand"/.test(fileContent);
31
+ lines.forEach((line, index) => {
32
+ const lineNumber = index + 1;
33
+ const trimmed = line.trim();
34
+ // Track multi-line comments (/* ... */)
35
+ if (trimmed.includes('/*')) {
36
+ inMultiLineComment = true;
37
+ }
38
+ if (trimmed.includes('*/')) {
39
+ inMultiLineComment = false;
40
+ return;
41
+ }
42
+ // Skip comments and empty lines
43
+ if (!trimmed || inMultiLineComment || trimmed.startsWith('//')) {
44
+ return;
45
+ }
46
+ // =============================================================================
47
+ // Check #1 & #2: Hardcoded Credentials (API Keys, Passwords, Secrets)
48
+ // =============================================================================
49
+ // CVSS 9.1 - CRITICAL
50
+ // Detects patterns like:
51
+ // - const APIKey = "sk-1234567890abcdef"
52
+ // - apiKey := "sk-1234567890abcdef"
53
+ // - Password: "SuperSecret123!"
54
+ // - var jwtSecret = "my-secret-key"
55
+ // Pattern 1: Variable assignment (const/var/identifier :=)
56
+ // Match both complete strings and multi-line strings (closing quote optional)
57
+ const credentialAssignmentMatch = trimmed.match(/(?:const|var)?\s*(\w*(?:password|passwd|pwd|secret|apikey|api_key|privatekey|private_key|authtoken|auth_token|dbpassword|db_password|jwtsecret|jwt_secret|token|key)\w*)\s*(?::=|=)\s*"([^"]{8,})"?/i);
58
+ if (credentialAssignmentMatch &&
59
+ !trimmed.includes('os.Getenv') &&
60
+ !trimmed.includes('os.LookupEnv') &&
61
+ !trimmed.includes('viper.Get') &&
62
+ !trimmed.includes('config.') &&
63
+ !trimmed.includes('fmt.Print') &&
64
+ !trimmed.includes('log.') &&
65
+ !trimmed.includes('// Example:') &&
66
+ !trimmed.includes('// DON\'T')) {
67
+ const credentialValue = credentialAssignmentMatch[2];
68
+ // Validation: check if value looks like a real credential
69
+ const isRealCredential = credentialValue.length >= 8 &&
70
+ !credentialValue.match(/^(test|example|demo|sample|fake|your|placeholder|xxx|changeme)/i) &&
71
+ !credentialValue.match(/^(.)\1+$/); // Skip repeated characters (e.g., "aaaaaaaa")
72
+ if (isRealCredential) {
73
+ vulnerabilities.push((0, createVulnerability_1.createGoSecurityVulnerability)({
74
+ category: 'go-hardcoded-credentials',
75
+ severity: 'critical',
76
+ confidence: 'high',
77
+ message: 'Hardcoded credentials exposed in source code',
78
+ line: lineNumber,
79
+ suggestion: 'Use environment variables with os.Getenv() or a secrets manager',
80
+ owasp: 'A07:2025 - Identification and Authentication Failures',
81
+ cwe: 'CWE-798',
82
+ pciDss: 'PCI DSS 6.5.10',
83
+ remediation: {
84
+ explanation: 'Hardcoded credentials in source code are visible to anyone with repository access and persist in Git history forever. They cannot be rotated without code changes and redeployment.',
85
+ before: `const APIKey = "sk-1234567890abcdef"`,
86
+ after: `import "os"\nconst APIKey = os.Getenv("API_KEY") // Store in environment variables`
87
+ },
88
+ attackVector: {
89
+ description: 'Hardcoded credentials allow attackers who gain repository access to authenticate as the application, bypassing all security controls.',
90
+ exploitExample: `// Attacker finds in Git history:\nconst DBPassword = "SuperSecret123!"\n// Gains full database access`,
91
+ realWorldImpact: [
92
+ 'Unauthorized access to APIs, databases, or cloud services',
93
+ 'Account takeover and privilege escalation',
94
+ 'Data breach and exfiltration',
95
+ 'Credentials cannot be rotated without code changes',
96
+ 'Exposed in version control history permanently'
97
+ ]
98
+ }
99
+ }));
100
+ }
101
+ }
102
+ // Pattern 2: Struct field assignment (Password: "...")
103
+ const structFieldMatch = trimmed.match(/(\w*(?:Password|Passwd|Pwd|Secret|APIKey|Api_key|PrivateKey|Private_key|AuthToken|Auth_token|DBPassword|Db_password|JWTSecret|Jwt_secret|Token|Key)\w*):\s*"([^"]{8,})"/i);
104
+ if (structFieldMatch &&
105
+ !trimmed.includes('os.Getenv') &&
106
+ !trimmed.includes('os.LookupEnv') &&
107
+ !trimmed.includes('viper.Get') &&
108
+ !trimmed.includes('config.') &&
109
+ !trimmed.includes('fmt.Print') &&
110
+ !trimmed.includes('log.')) {
111
+ const credentialValue = structFieldMatch[2];
112
+ const isRealCredential = credentialValue.length >= 8 &&
113
+ !credentialValue.match(/^(test|example|demo|sample|fake|your|placeholder|xxx|changeme)/i) &&
114
+ !credentialValue.match(/^(.)\1+$/);
115
+ if (isRealCredential) {
116
+ vulnerabilities.push((0, createVulnerability_1.createGoSecurityVulnerability)({
117
+ category: 'go-hardcoded-credentials',
118
+ severity: 'critical',
119
+ confidence: 'high',
120
+ message: 'Hardcoded credentials in struct initialization',
121
+ line: lineNumber,
122
+ suggestion: 'Use environment variables with os.Getenv() or a secrets manager',
123
+ owasp: 'A07:2025 - Identification and Authentication Failures',
124
+ cwe: 'CWE-798',
125
+ pciDss: 'PCI DSS 6.5.10',
126
+ remediation: {
127
+ explanation: 'Hardcoded credentials in struct literals are visible to anyone with repository access. Use environment variables or a secrets manager like HashiCorp Vault.',
128
+ before: `config := Config{\n DBPassword: "SuperSecret123!",\n}`,
129
+ after: `import "os"\nconfig := Config{\n DBPassword: os.Getenv("DB_PASSWORD"),\n}`
130
+ },
131
+ attackVector: {
132
+ description: 'Hardcoded credentials in configuration structs allow attackers to extract sensitive data by reading source code or compiled binaries.',
133
+ exploitExample: `// Found in code:\nDBConfig{Password: "prod_db_pass_2024"}\n// Attacker gains production database access`,
134
+ realWorldImpact: [
135
+ 'Unauthorized database or API access',
136
+ 'Account takeover',
137
+ 'Data breach',
138
+ 'Credentials persist in Git history',
139
+ 'Cannot rotate credentials without code deployment'
140
+ ]
141
+ }
142
+ }));
143
+ }
144
+ }
145
+ // =============================================================================
146
+ // Check #3: Weak Password Hashing (MD5/SHA1)
147
+ // =============================================================================
148
+ // CVSS 8.5 - HIGH
149
+ // Detects MD5 or SHA1 being used for password hashing
150
+ const hasPasswordContext = /password|passwd|pwd|credential|auth/i.test(trimmed);
151
+ const hasWeakHash = /(md5|sha1)/i.test(trimmed);
152
+ const hasCryptoImport = /crypto\/(md5|sha1)/i.test(trimmed);
153
+ // Check for MD5/SHA1 usage in password context
154
+ // Only flag if: (password context AND weak hash) OR (crypto import AND password in file)
155
+ const fileHasPasswordContext = /password|passwd|pwd|credential|auth/i.test(fileContent);
156
+ if ((hasPasswordContext && hasWeakHash) || (hasCryptoImport && fileHasPasswordContext)) {
157
+ // Additional context check - look for actual hashing operations
158
+ const hasHashingOperation = /\.Sum\(|\.Write\(|New\(\)/.test(trimmed) || /md5|sha1/.test(trimmed.toLowerCase());
159
+ if (hasHashingOperation || (hasCryptoImport && fileHasPasswordContext)) {
160
+ vulnerabilities.push((0, createVulnerability_1.createGoSecurityVulnerability)({
161
+ category: 'go-weak-hashing',
162
+ severity: 'high',
163
+ confidence: 'high',
164
+ message: 'Weak cryptographic hash (MD5/SHA1) used for password hashing',
165
+ line: lineNumber,
166
+ suggestion: 'Use bcrypt, scrypt, or Argon2 for password hashing',
167
+ owasp: 'A02:2025 - Cryptographic Failures',
168
+ cwe: 'CWE-327',
169
+ pciDss: 'PCI DSS 6.5.3',
170
+ remediation: {
171
+ explanation: 'MD5 and SHA1 are fast hash functions designed for integrity checking, not password storage. They are vulnerable to brute-force and rainbow table attacks. Use password-specific algorithms like bcrypt, scrypt, or Argon2.',
172
+ before: `import "crypto/md5"\nhash := md5.Sum([]byte(password))`,
173
+ after: `import "golang.org/x/crypto/bcrypt"\nhash, _ := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)`
174
+ },
175
+ attackVector: {
176
+ description: 'MD5 and SHA1 hashes can be cracked in seconds using rainbow tables or GPU-accelerated brute force. Attackers who obtain the password database can easily recover plaintext passwords.',
177
+ exploitExample: `// Weak hashing:\nmd5Hash := md5.Sum([]byte(password))\n// Attacker uses hashcat to crack in <1 second`,
178
+ realWorldImpact: [
179
+ 'Password database compromises lead to plaintext password recovery',
180
+ 'Account takeover across multiple services (password reuse)',
181
+ 'Compliance violations (PCI DSS, GDPR)',
182
+ 'Regulatory fines and reputation damage'
183
+ ]
184
+ }
185
+ }));
186
+ }
187
+ }
188
+ // =============================================================================
189
+ // Check #4: Weak Random Number Generation (math/rand)
190
+ // =============================================================================
191
+ // CVSS 8.1 - HIGH
192
+ // Detects math/rand being used for security-critical operations
193
+ const hasSecurityContext = /token|secret|password|session|nonce|salt|csrf|api[_-]?key|auth/i.test(trimmed);
194
+ const hasRandOperation = /rand\.(Int|Intn|Read|Float|Shuffle|Perm)/i.test(trimmed) || /rand\.\w+\(/.test(trimmed);
195
+ // Only flag if:
196
+ // 1. Line has security context AND rand operation
197
+ // 2. File imports math/rand (not crypto/rand)
198
+ // 3. OR line explicitly mentions math/rand
199
+ const explicitMathRand = /math\/rand/.test(trimmed);
200
+ const isWeakRandom = hasRandOperation && (explicitMathRand || (hasMathRandImport && !hasCryptoRandImport));
201
+ if (hasSecurityContext && isWeakRandom) {
202
+ vulnerabilities.push((0, createVulnerability_1.createGoSecurityVulnerability)({
203
+ category: 'go-weak-random',
204
+ severity: 'high',
205
+ confidence: 'high',
206
+ message: 'Weak random number generation (math/rand) for security-critical operation',
207
+ line: lineNumber,
208
+ suggestion: 'Use crypto/rand for security-critical random number generation',
209
+ owasp: 'A02:2025 - Cryptographic Failures',
210
+ cwe: 'CWE-338',
211
+ pciDss: 'PCI DSS 6.5.3',
212
+ remediation: {
213
+ explanation: 'math/rand is a pseudo-random number generator (PRNG) designed for simulations and games, not cryptography. It is predictable and can be reversed. Use crypto/rand for tokens, secrets, and all security-critical randomness.',
214
+ before: `import "math/rand"\ntoken := rand.Intn(1000000) // Predictable`,
215
+ after: `import "crypto/rand"\nimport "encoding/base64"\nbytes := make([]byte, 32)\ncrypto/rand.Read(bytes)\ntoken := base64.URLEncoding.EncodeToString(bytes)`
216
+ },
217
+ attackVector: {
218
+ description: 'math/rand uses a deterministic algorithm that can be predicted or reversed if the seed is known. Attackers can predict session tokens, API keys, CSRF tokens, and other secrets.',
219
+ exploitExample: `// Weak token generation:\nsessionToken := rand.Intn(999999)\n// Attacker predicts token sequence and hijacks sessions`,
220
+ realWorldImpact: [
221
+ 'Session hijacking and account takeover',
222
+ 'CSRF token prediction enabling CSRF attacks',
223
+ 'API key prediction enabling unauthorized access',
224
+ 'Cryptographic salt prediction weakening password hashes'
225
+ ]
226
+ }
227
+ }));
228
+ }
229
+ // Special case: Detect math/rand import in files that handle security
230
+ // Only check actual import statements, not comments
231
+ const isMathRandImport = trimmed === 'import "math/rand"' || trimmed === '"math/rand"';
232
+ if (isMathRandImport && hasMathRandImport) {
233
+ // Check if the file likely deals with security (heuristic)
234
+ const hasSecurityKeywords = /password|token|secret|session|auth|crypto|security|key|csrf/.test(fileContent.toLowerCase());
235
+ if (hasSecurityKeywords) {
236
+ vulnerabilities.push((0, createVulnerability_1.createGoSecurityVulnerability)({
237
+ category: 'go-weak-random',
238
+ severity: 'high',
239
+ confidence: 'medium',
240
+ message: 'math/rand imported in security-sensitive file - use crypto/rand instead',
241
+ line: lineNumber,
242
+ suggestion: 'Replace math/rand with crypto/rand for all security-critical operations',
243
+ owasp: 'A02:2025 - Cryptographic Failures',
244
+ cwe: 'CWE-338',
245
+ pciDss: 'PCI DSS 6.5.3',
246
+ remediation: {
247
+ explanation: 'Files that handle authentication, tokens, or cryptography should never use math/rand. Use crypto/rand for all random number generation in security contexts.',
248
+ before: `import "math/rand"`,
249
+ after: `import "crypto/rand"`
250
+ },
251
+ attackVector: {
252
+ description: 'Using math/rand in security-sensitive files indicates potential weak random number generation throughout the codebase.',
253
+ exploitExample: `// In auth.go:\nimport "math/rand"\n// Any token/secret generation is now weak`,
254
+ realWorldImpact: [
255
+ 'Predictable tokens and secrets',
256
+ 'Session hijacking',
257
+ 'Authentication bypass',
258
+ 'Cryptographic key prediction'
259
+ ]
260
+ }
261
+ }));
262
+ }
263
+ }
264
+ });
265
+ return vulnerabilities;
266
+ }
267
+ //# sourceMappingURL=credentials-crypto.js.map