@havoc-security/scanner 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 (140) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-test.log +22 -0
  3. package/dist/analyzers/AuthorizationCoverageAnalyzer.d.ts +7 -0
  4. package/dist/analyzers/AuthorizationCoverageAnalyzer.d.ts.map +1 -0
  5. package/dist/analyzers/AuthorizationCoverageAnalyzer.js +100 -0
  6. package/dist/analyzers/AuthorizationCoverageAnalyzer.js.map +1 -0
  7. package/dist/analyzers/CredentialExposureAnalyzer.d.ts +11 -0
  8. package/dist/analyzers/CredentialExposureAnalyzer.d.ts.map +1 -0
  9. package/dist/analyzers/CredentialExposureAnalyzer.js +262 -0
  10. package/dist/analyzers/CredentialExposureAnalyzer.js.map +1 -0
  11. package/dist/analyzers/DependencyAuditAnalyzer.d.ts +28 -0
  12. package/dist/analyzers/DependencyAuditAnalyzer.d.ts.map +1 -0
  13. package/dist/analyzers/DependencyAuditAnalyzer.js +107 -0
  14. package/dist/analyzers/DependencyAuditAnalyzer.js.map +1 -0
  15. package/dist/analyzers/EncryptionAnalyzer.d.ts +7 -0
  16. package/dist/analyzers/EncryptionAnalyzer.d.ts.map +1 -0
  17. package/dist/analyzers/EncryptionAnalyzer.js +170 -0
  18. package/dist/analyzers/EncryptionAnalyzer.js.map +1 -0
  19. package/dist/analyzers/FileUploadAnalyzer.d.ts +8 -0
  20. package/dist/analyzers/FileUploadAnalyzer.d.ts.map +1 -0
  21. package/dist/analyzers/FileUploadAnalyzer.js +193 -0
  22. package/dist/analyzers/FileUploadAnalyzer.js.map +1 -0
  23. package/dist/analyzers/IdorAnalyzer.d.ts +7 -0
  24. package/dist/analyzers/IdorAnalyzer.d.ts.map +1 -0
  25. package/dist/analyzers/IdorAnalyzer.js +91 -0
  26. package/dist/analyzers/IdorAnalyzer.js.map +1 -0
  27. package/dist/analyzers/MassAssignmentAnalyzer.d.ts +7 -0
  28. package/dist/analyzers/MassAssignmentAnalyzer.d.ts.map +1 -0
  29. package/dist/analyzers/MassAssignmentAnalyzer.js +90 -0
  30. package/dist/analyzers/MassAssignmentAnalyzer.js.map +1 -0
  31. package/dist/analyzers/PrivilegeEscalationAnalyzer.d.ts +7 -0
  32. package/dist/analyzers/PrivilegeEscalationAnalyzer.d.ts.map +1 -0
  33. package/dist/analyzers/PrivilegeEscalationAnalyzer.js +217 -0
  34. package/dist/analyzers/PrivilegeEscalationAnalyzer.js.map +1 -0
  35. package/dist/analyzers/RateLimitAnalyzer.d.ts +7 -0
  36. package/dist/analyzers/RateLimitAnalyzer.d.ts.map +1 -0
  37. package/dist/analyzers/RateLimitAnalyzer.js +151 -0
  38. package/dist/analyzers/RateLimitAnalyzer.js.map +1 -0
  39. package/dist/analyzers/SessionSecurityAnalyzer.d.ts +10 -0
  40. package/dist/analyzers/SessionSecurityAnalyzer.d.ts.map +1 -0
  41. package/dist/analyzers/SessionSecurityAnalyzer.js +295 -0
  42. package/dist/analyzers/SessionSecurityAnalyzer.js.map +1 -0
  43. package/dist/analyzers/SqlInjectionAnalyzer.d.ts +7 -0
  44. package/dist/analyzers/SqlInjectionAnalyzer.d.ts.map +1 -0
  45. package/dist/analyzers/SqlInjectionAnalyzer.js +77 -0
  46. package/dist/analyzers/SqlInjectionAnalyzer.js.map +1 -0
  47. package/dist/analyzers/XssSurfaceAnalyzer.d.ts +7 -0
  48. package/dist/analyzers/XssSurfaceAnalyzer.d.ts.map +1 -0
  49. package/dist/analyzers/XssSurfaceAnalyzer.js +100 -0
  50. package/dist/analyzers/XssSurfaceAnalyzer.js.map +1 -0
  51. package/dist/analyzers/index.d.ts +13 -0
  52. package/dist/analyzers/index.d.ts.map +1 -0
  53. package/dist/analyzers/index.js +13 -0
  54. package/dist/analyzers/index.js.map +1 -0
  55. package/dist/index.d.ts +17 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +139 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/parsers/PhpParser.d.ts +56 -0
  60. package/dist/parsers/PhpParser.d.ts.map +1 -0
  61. package/dist/parsers/PhpParser.js +193 -0
  62. package/dist/parsers/PhpParser.js.map +1 -0
  63. package/dist/parsers/RouteParser.d.ts +87 -0
  64. package/dist/parsers/RouteParser.d.ts.map +1 -0
  65. package/dist/parsers/RouteParser.js +327 -0
  66. package/dist/parsers/RouteParser.js.map +1 -0
  67. package/dist/rules/index.d.ts +14 -0
  68. package/dist/rules/index.d.ts.map +1 -0
  69. package/dist/rules/index.js +9 -0
  70. package/dist/rules/index.js.map +1 -0
  71. package/dist/types/index.d.ts +137 -0
  72. package/dist/types/index.d.ts.map +1 -0
  73. package/dist/types/index.js +13 -0
  74. package/dist/types/index.js.map +1 -0
  75. package/package.json +30 -0
  76. package/package.json.bak +27 -0
  77. package/src/analyzers/AuthorizationCoverageAnalyzer.ts +213 -0
  78. package/src/analyzers/CredentialExposureAnalyzer.ts +312 -0
  79. package/src/analyzers/DependencyAuditAnalyzer.ts +135 -0
  80. package/src/analyzers/EncryptionAnalyzer.ts +195 -0
  81. package/src/analyzers/FileUploadAnalyzer.ts +239 -0
  82. package/src/analyzers/IdorAnalyzer.ts +118 -0
  83. package/src/analyzers/InsecureDeserializationAnalyzer.ts +212 -0
  84. package/src/analyzers/MassAssignmentAnalyzer.ts +105 -0
  85. package/src/analyzers/OpenRedirectAnalyzer.ts +149 -0
  86. package/src/analyzers/PrivilegeEscalationAnalyzer.ts +258 -0
  87. package/src/analyzers/RateLimitAnalyzer.ts +195 -0
  88. package/src/analyzers/SecurityHeaderAnalyzer.ts +263 -0
  89. package/src/analyzers/SessionSecurityAnalyzer.ts +342 -0
  90. package/src/analyzers/SqlInjectionAnalyzer.ts +99 -0
  91. package/src/analyzers/XssSurfaceAnalyzer.ts +112 -0
  92. package/src/analyzers/exclusions.ts +87 -0
  93. package/src/analyzers/index.ts +15 -0
  94. package/src/index.ts +226 -0
  95. package/src/parsers/PhpParser.ts +259 -0
  96. package/src/parsers/RouteParser.ts +384 -0
  97. package/src/rules/index.ts +16 -0
  98. package/src/types/index.ts +164 -0
  99. package/tests/EncryptionAnalyzer.test.ts +137 -0
  100. package/tests/PrivilegeEscalationAnalyzer.test.ts +141 -0
  101. package/tests/RateLimitAnalyzer.test.ts +112 -0
  102. package/tests/analyzers.test.ts +678 -0
  103. package/tests/auth-coverage-route-aware.test.ts +294 -0
  104. package/tests/credential-exposure.test.ts +142 -0
  105. package/tests/file-upload.test.ts +141 -0
  106. package/tests/fixtures/app/Http/Controllers/AdminController.php +19 -0
  107. package/tests/fixtures/app/Http/Controllers/PostController.php +49 -0
  108. package/tests/fixtures/app/Http/Controllers/PublicController.php +17 -0
  109. package/tests/fixtures/app/Models/Comment.php +11 -0
  110. package/tests/fixtures/app/Models/OpenModel.php +11 -0
  111. package/tests/fixtures/app/Models/Post.php +14 -0
  112. package/tests/fixtures/app/Models/SafeModel.php +10 -0
  113. package/tests/fixtures/app/Models/User.php +15 -0
  114. package/tests/fixtures/blade/mail.blade.php +8 -0
  115. package/tests/fixtures/blade/safe.blade.php +12 -0
  116. package/tests/fixtures/blade/vulnerable.blade.php +12 -0
  117. package/tests/fixtures/controllers/AdminController.php +19 -0
  118. package/tests/fixtures/controllers/PostController.php +49 -0
  119. package/tests/fixtures/controllers/PublicController.php +17 -0
  120. package/tests/fixtures/deserialization/safe.php +32 -0
  121. package/tests/fixtures/deserialization/unsafe.php +60 -0
  122. package/tests/fixtures/models/Comment.php +11 -0
  123. package/tests/fixtures/models/OpenModel.php +11 -0
  124. package/tests/fixtures/models/Post.php +14 -0
  125. package/tests/fixtures/models/SafeModel.php +10 -0
  126. package/tests/fixtures/models/User.php +15 -0
  127. package/tests/fixtures/redirect/safe.php +38 -0
  128. package/tests/fixtures/redirect/unsafe.php +39 -0
  129. package/tests/fixtures/routes/api.php +9 -0
  130. package/tests/fixtures/routes/web.php +18 -0
  131. package/tests/fixtures/security-headers/app/Http/Middleware/SecurityHeaders.php +24 -0
  132. package/tests/fixtures/security-headers/app/Providers/AppServiceProvider.php +16 -0
  133. package/tests/fixtures/sql/safe_queries.php +7 -0
  134. package/tests/fixtures/sql/vulnerable_queries.php +7 -0
  135. package/tests/new-analyzers.test.ts +373 -0
  136. package/tests/route-parser.test.ts +257 -0
  137. package/tests/scanner.test.ts +82 -0
  138. package/tests/session-security.test.ts +161 -0
  139. package/tests/types.test.ts +29 -0
  140. package/tsconfig.json +9 -0
@@ -0,0 +1,295 @@
1
+ import { Severity } from '../types/index.js';
2
+ // ─── Constants ────────────────────────────────────────────────────────────────
3
+ const ANALYZER_NAME = 'SessionSecurityAnalyzer';
4
+ const FINDING_SECURE_COOKIE = 'HAVOC-SESS-001';
5
+ const FINDING_HTTP_ONLY = 'HAVOC-SESS-002';
6
+ const FINDING_SAME_SITE = 'HAVOC-SESS-003';
7
+ const FINDING_FILE_DRIVER = 'HAVOC-SESS-004';
8
+ const FINDING_CSRF_EXCLUSION = 'HAVOC-SESS-005';
9
+ const FINDING_SESSION_LIFETIME = 'HAVOC-SESS-006';
10
+ const FINDING_COOKIE_ENCRYPTION = 'HAVOC-SESS-007';
11
+ const SESSION_LIFETIME_THRESHOLD = 480; // minutes
12
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
13
+ function isSessionConfig(path) {
14
+ return path === 'config/session.php' || path.endsWith('/config/session.php');
15
+ }
16
+ function isBootstrapApp(path) {
17
+ return path === 'bootstrap/app.php' || path.endsWith('/bootstrap/app.php');
18
+ }
19
+ function isMiddlewareFile(path) {
20
+ return path.includes('Middleware') && path.endsWith('.php');
21
+ }
22
+ function findLineNumber(content, matchIndex) {
23
+ return content.slice(0, matchIndex).split('\n').length;
24
+ }
25
+ /**
26
+ * Extract a config value from a PHP config file.
27
+ *
28
+ * Handles:
29
+ * - scalar booleans: `'key' => true`
30
+ * - scalar strings: `'key' => 'value'`
31
+ * - env() calls with inner commas: `'key' => env('VAR', 'default')`
32
+ * - integer literals: `'key' => 120`
33
+ *
34
+ * Returns the raw matched value string, or null if the key isn't found.
35
+ */
36
+ function extractConfigValue(content, key) {
37
+ // Match the key, then capture either:
38
+ // - an env(...) call (balancing parentheses up to closing paren)
39
+ // - a quoted string
40
+ // - a bare token (true/false/null/number)
41
+ const keyPattern = new RegExp(`['"]${key}['"]\\s*=>\\s*`, 'i');
42
+ const keyMatch = keyPattern.exec(content);
43
+ if (!keyMatch)
44
+ return null;
45
+ const afterKey = content.slice(keyMatch.index + keyMatch[0].length);
46
+ // env(...) call — capture to the matching close paren
47
+ const envCallMatch = /^env\s*\(/.exec(afterKey);
48
+ if (envCallMatch) {
49
+ let depth = 0;
50
+ let i = afterKey.indexOf('(');
51
+ for (; i < afterKey.length; i++) {
52
+ if (afterKey[i] === '(')
53
+ depth++;
54
+ else if (afterKey[i] === ')') {
55
+ depth--;
56
+ if (depth === 0)
57
+ return afterKey.slice(0, i + 1).trim();
58
+ }
59
+ }
60
+ return afterKey.slice(0, 60).trim(); // fallback
61
+ }
62
+ // Quoted string: 'value' or "value"
63
+ const quotedMatch = /^(['"])(.*?)\1/.exec(afterKey);
64
+ if (quotedMatch)
65
+ return quotedMatch[0].trim();
66
+ // Bare token: true, false, null, or integer — stop at comma or newline
67
+ const bareMatch = /^[^\s,\n\r]+/.exec(afterKey);
68
+ if (bareMatch)
69
+ return bareMatch[0].trim();
70
+ return null;
71
+ }
72
+ /**
73
+ * Unwrap env(...) call to extract the default value (second argument).
74
+ * e.g., `env('SESSION_SECURE_COOKIE', false)` → 'false'
75
+ */
76
+ function extractEnvDefault(envCall) {
77
+ const match = /env\s*\([^,)]+,\s*(.+?)\s*\)$/.exec(envCall.trim());
78
+ if (!match)
79
+ return null;
80
+ return match[1].replace(/['"]/g, '').trim();
81
+ }
82
+ // ─── Analyzer ─────────────────────────────────────────────────────────────────
83
+ export class SessionSecurityAnalyzer {
84
+ name = ANALYZER_NAME;
85
+ description = 'Analyzes session and cookie security configuration for vulnerabilities';
86
+ async analyze(files, _config) {
87
+ const findings = [];
88
+ for (const file of files) {
89
+ if (!file.path.endsWith('.php'))
90
+ continue;
91
+ if (isSessionConfig(file.path)) {
92
+ findings.push(...this.analyzeSessionConfig(file));
93
+ }
94
+ if (isBootstrapApp(file.path) || isMiddlewareFile(file.path)) {
95
+ findings.push(...this.analyzeCsrfExclusions(file));
96
+ findings.push(...this.analyzeCookieEncryption(file));
97
+ }
98
+ }
99
+ return findings;
100
+ }
101
+ analyzeSessionConfig(file) {
102
+ const findings = [];
103
+ const content = file.content;
104
+ // Check 'secure' flag — should be true (or env-driven default true) in production
105
+ const secureValue = extractConfigValue(content, 'secure');
106
+ if (secureValue !== null) {
107
+ let isInsecure = false;
108
+ if (secureValue === 'false') {
109
+ isInsecure = true;
110
+ }
111
+ else if (/^env\s*\(/.test(secureValue)) {
112
+ const defaultVal = extractEnvDefault(secureValue);
113
+ if (defaultVal === 'false')
114
+ isInsecure = true;
115
+ }
116
+ if (isInsecure) {
117
+ const idx = content.search(/'secure'\s*=>/i);
118
+ findings.push({
119
+ id: FINDING_SECURE_COOKIE,
120
+ severity: Severity.High,
121
+ analyzer: ANALYZER_NAME,
122
+ title: 'Session cookie `secure` flag is disabled',
123
+ description: `\`'secure' => false\` in \`${file.path}\`. ` +
124
+ `Session cookies without the Secure flag can be transmitted over unencrypted HTTP connections.`,
125
+ file: file.path,
126
+ line: idx !== -1 ? findLineNumber(content, idx) : 1,
127
+ recommendation: "Set `'secure' => env('SESSION_SECURE_COOKIE', true)` to ensure cookies are only sent over HTTPS.",
128
+ cwe: 'CWE-614',
129
+ snippet: `'secure' => false`,
130
+ });
131
+ }
132
+ }
133
+ // Check 'http_only' — should be true
134
+ const httpOnlyValue = extractConfigValue(content, 'http_only');
135
+ if (httpOnlyValue !== null && httpOnlyValue === 'false') {
136
+ const idx = content.search(/'http_only'\s*=>/i);
137
+ findings.push({
138
+ id: FINDING_HTTP_ONLY,
139
+ severity: Severity.High,
140
+ analyzer: ANALYZER_NAME,
141
+ title: 'Session cookie `http_only` flag is disabled',
142
+ description: `\`'http_only' => false\` in \`${file.path}\`. ` +
143
+ `Without the HttpOnly flag, session cookies can be accessed by client-side JavaScript, enabling XSS-based session theft.`,
144
+ file: file.path,
145
+ line: idx !== -1 ? findLineNumber(content, idx) : 1,
146
+ recommendation: "Set `'http_only' => true` to prevent JavaScript access to session cookies.",
147
+ cwe: 'CWE-1004',
148
+ snippet: `'http_only' => false`,
149
+ });
150
+ }
151
+ // Check 'same_site' — should be 'lax' or 'strict'
152
+ const sameSiteValue = extractConfigValue(content, 'same_site');
153
+ if (sameSiteValue !== null) {
154
+ const cleaned = sameSiteValue.replace(/['"]/g, '').toLowerCase().trim();
155
+ if (cleaned === 'none' || cleaned === 'null' || cleaned === '') {
156
+ const idx = content.search(/'same_site'\s*=>/i);
157
+ findings.push({
158
+ id: FINDING_SAME_SITE,
159
+ severity: Severity.Medium,
160
+ analyzer: ANALYZER_NAME,
161
+ title: `Session cookie \`same_site\` is set to \`${cleaned || 'null'}\``,
162
+ description: `\`'same_site' => '${cleaned}'\` in \`${file.path}\`. ` +
163
+ `A permissive SameSite policy increases CSRF attack surface.`,
164
+ file: file.path,
165
+ line: idx !== -1 ? findLineNumber(content, idx) : 1,
166
+ recommendation: "Set `'same_site' => 'lax'` or `'strict'` to mitigate CSRF attacks.",
167
+ cwe: 'CWE-352',
168
+ snippet: `'same_site' => '${cleaned}'`,
169
+ });
170
+ }
171
+ }
172
+ // Check 'driver' — warn if 'file' (should be redis/database in production)
173
+ const driverValue = extractConfigValue(content, 'driver');
174
+ if (driverValue !== null) {
175
+ let driverStr = driverValue.replace(/['"]/g, '').trim();
176
+ // If env-driven, extract default
177
+ if (/^env\s*\(/.test(driverValue)) {
178
+ const def = extractEnvDefault(driverValue);
179
+ driverStr = def ?? driverStr;
180
+ }
181
+ if (driverStr === 'file') {
182
+ const idx = content.search(/'driver'\s*=>/i);
183
+ findings.push({
184
+ id: FINDING_FILE_DRIVER,
185
+ severity: Severity.Medium,
186
+ analyzer: ANALYZER_NAME,
187
+ title: 'Session driver is set to `file`',
188
+ description: `\`'driver' => 'file'\` in \`${file.path}\`. ` +
189
+ `File-based session storage is not suitable for production — it doesn't scale across multiple servers.`,
190
+ file: file.path,
191
+ line: idx !== -1 ? findLineNumber(content, idx) : 1,
192
+ recommendation: "Use `'driver' => env('SESSION_DRIVER', 'redis')` and configure Redis or database session storage in production.",
193
+ cwe: 'CWE-16',
194
+ snippet: `'driver' => 'file'`,
195
+ });
196
+ }
197
+ }
198
+ // Check session lifetime > 480 minutes
199
+ const lifetimeValue = extractConfigValue(content, 'lifetime');
200
+ if (lifetimeValue !== null) {
201
+ const numStr = lifetimeValue.replace(/[^0-9]/g, '');
202
+ const lifetimeNum = parseInt(numStr, 10);
203
+ if (!isNaN(lifetimeNum) && lifetimeNum > SESSION_LIFETIME_THRESHOLD) {
204
+ const idx = content.search(/'lifetime'\s*=>/i);
205
+ findings.push({
206
+ id: FINDING_SESSION_LIFETIME,
207
+ severity: Severity.Medium,
208
+ analyzer: ANALYZER_NAME,
209
+ title: `Session lifetime is excessively long (${lifetimeNum} minutes)`,
210
+ description: `Session lifetime of ${lifetimeNum} minutes in \`${file.path}\` exceeds the recommended maximum of ${SESSION_LIFETIME_THRESHOLD} minutes (8 hours). ` +
211
+ `Long-lived sessions increase the window of opportunity for session hijacking.`,
212
+ file: file.path,
213
+ line: idx !== -1 ? findLineNumber(content, idx) : 1,
214
+ recommendation: `Set the session lifetime to ${SESSION_LIFETIME_THRESHOLD} minutes or less and implement idle timeout.`,
215
+ cwe: 'CWE-613',
216
+ snippet: `'lifetime' => ${lifetimeNum}`,
217
+ });
218
+ }
219
+ }
220
+ return findings;
221
+ }
222
+ analyzeCsrfExclusions(file) {
223
+ const findings = [];
224
+ const content = file.content;
225
+ // Gate to VerifyCsrfToken-specific files: check by filename or class/use declarations
226
+ const isCsrfMiddleware = file.path.includes('VerifyCsrfToken') ||
227
+ /class\s+VerifyCsrfToken/.test(content) ||
228
+ (/VerifyCsrfToken/.test(content) && !content.includes('class EncryptCookies'));
229
+ if (isCsrfMiddleware) {
230
+ const hasExceptArray = /\$except\s*=\s*\[([^\]]+)\]/.exec(content);
231
+ if (hasExceptArray && hasExceptArray[1].trim() !== '') {
232
+ const idx = content.search(/\$except\s*=\s*\[/);
233
+ findings.push({
234
+ id: FINDING_CSRF_EXCLUSION,
235
+ severity: Severity.High,
236
+ analyzer: ANALYZER_NAME,
237
+ title: 'CSRF token verification is excluded for some routes',
238
+ description: `\`$except\` array with routes is defined in \`${file.path}\`. ` +
239
+ `Excluding routes from CSRF verification leaves them vulnerable to cross-site request forgery attacks.`,
240
+ file: file.path,
241
+ line: idx !== -1 ? findLineNumber(content, idx) : 1,
242
+ recommendation: 'Remove CSRF exclusions unless absolutely necessary. For API routes, use token-based auth instead.',
243
+ cwe: 'CWE-352',
244
+ snippet: hasExceptArray[0].slice(0, 80),
245
+ });
246
+ }
247
+ }
248
+ // Check bootstrap/app.php for withoutMiddleware(VerifyCsrfToken)
249
+ const withoutCsrf = /withoutMiddleware\s*\(\s*(?:[^)]*VerifyCsrfToken[^)]*)\)/.exec(content);
250
+ if (withoutCsrf) {
251
+ findings.push({
252
+ id: FINDING_CSRF_EXCLUSION,
253
+ severity: Severity.High,
254
+ analyzer: ANALYZER_NAME,
255
+ title: 'CSRF middleware explicitly disabled for routes',
256
+ description: `\`withoutMiddleware(VerifyCsrfToken::class)\` found in \`${file.path}\`. ` +
257
+ `Disabling CSRF verification exposes endpoints to cross-site request forgery.`,
258
+ file: file.path,
259
+ line: findLineNumber(content, withoutCsrf.index),
260
+ recommendation: 'Use proper API authentication (Sanctum, Passport) for routes that need to skip web CSRF middleware.',
261
+ cwe: 'CWE-352',
262
+ snippet: withoutCsrf[0].slice(0, 80),
263
+ });
264
+ }
265
+ return findings;
266
+ }
267
+ analyzeCookieEncryption(file) {
268
+ const findings = [];
269
+ const content = file.content;
270
+ // Only check EncryptCookies middleware files
271
+ const isEncryptCookiesFile = file.path.includes('EncryptCookies') ||
272
+ /class\s+EncryptCookies/.test(content);
273
+ if (isEncryptCookiesFile) {
274
+ const exceptMatch = /\$except\s*=\s*\[([^\]]+)\]/.exec(content);
275
+ if (exceptMatch && exceptMatch[1].trim() !== '') {
276
+ const idx = content.search(/\$except\s*=\s*\[/);
277
+ findings.push({
278
+ id: FINDING_COOKIE_ENCRYPTION,
279
+ severity: Severity.Medium,
280
+ analyzer: ANALYZER_NAME,
281
+ title: 'Sensitive cookies may be excluded from encryption',
282
+ description: `The \`$except\` array in \`${file.path}\` excludes some cookies from encryption. ` +
283
+ `Unencrypted cookies can be read or tampered with by the client.`,
284
+ file: file.path,
285
+ line: idx !== -1 ? findLineNumber(content, idx) : 1,
286
+ recommendation: 'Only exclude cookies that are explicitly designed to be readable client-side. Remove sensitive cookie names from `$except`.',
287
+ cwe: 'CWE-311',
288
+ snippet: exceptMatch[0].slice(0, 80),
289
+ });
290
+ }
291
+ }
292
+ return findings;
293
+ }
294
+ }
295
+ //# sourceMappingURL=SessionSecurityAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionSecurityAnalyzer.js","sourceRoot":"","sources":["../../src/analyzers/SessionSecurityAnalyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { Analyzer, Finding, HavocConfig, ParsedFile } from '../types/index.js';
2
+ export declare class SqlInjectionAnalyzer implements Analyzer {
3
+ readonly name = "SqlInjectionAnalyzer";
4
+ readonly description = "Finds raw SQL queries with potential injection vulnerabilities";
5
+ analyze(files: ParsedFile[], _config: HavocConfig): Promise<Finding[]>;
6
+ }
7
+ //# sourceMappingURL=SqlInjectionAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SqlInjectionAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyzers/SqlInjectionAnalyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAY,MAAM,mBAAmB,CAAC;AAkDzF,qBAAa,oBAAqB,YAAW,QAAQ;IACnD,QAAQ,CAAC,IAAI,0BAAiB;IAC9B,QAAQ,CAAC,WAAW,oEAAoE;IAElF,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;CA4C7E"}
@@ -0,0 +1,77 @@
1
+ import { Severity } from '../types/index.js';
2
+ const RAW_SQL_METHODS = [
3
+ 'whereRaw', 'orWhereRaw', 'orderByRaw', 'selectRaw',
4
+ 'havingRaw', 'orHavingRaw', 'groupByRaw', 'fromRaw',
5
+ ];
6
+ const DB_FACADE_METHODS = [
7
+ 'DB::raw', 'DB::statement', 'DB::select', 'DB::insert', 'DB::update', 'DB::delete',
8
+ ];
9
+ // Matches: "str" . $var, "$var inside string", $var . 'str'
10
+ const INTERPOLATION_PATTERN = /(?:['"]\s*\.\s*\$|\$\{[^}]+\}|"[^"]*\$[a-zA-Z_][a-zA-Z0-9_]*[^"]*"|\$[a-zA-Z_][a-zA-Z0-9_]*\s*\.\s*['"])/;
11
+ // Matches ? placeholders or :named (but NOT ::method calls)
12
+ const BINDING_PATTERN = /\[\s*\$|\?\s*[,\]]|(?<![:])\s*:\s*(?!:)[a-zA-Z_]\w*/;
13
+ const FINDING_INJECTION = 'HAVOC-SQL-001';
14
+ const FINDING_RAW_INFO = 'HAVOC-SQL-002';
15
+ const ANALYZER_NAME = 'SqlInjectionAnalyzer';
16
+ function findRawSqlUsages(content) {
17
+ const lines = content.split('\n');
18
+ const matches = [];
19
+ lines.forEach((lineText, idx) => {
20
+ const lineNum = idx + 1;
21
+ for (const method of [...RAW_SQL_METHODS, ...DB_FACADE_METHODS]) {
22
+ const escaped = method.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
23
+ const methodPattern = new RegExp(`${escaped}\\s*\\(`, 'g');
24
+ if (methodPattern.test(lineText)) {
25
+ const hasInterpolation = INTERPOLATION_PATTERN.test(lineText);
26
+ const hasBinding = BINDING_PATTERN.test(lineText);
27
+ matches.push({ method, line: lineNum, snippet: lineText.trim(), hasInterpolation, hasBinding });
28
+ }
29
+ }
30
+ });
31
+ return matches;
32
+ }
33
+ export class SqlInjectionAnalyzer {
34
+ name = ANALYZER_NAME;
35
+ description = 'Finds raw SQL queries with potential injection vulnerabilities';
36
+ async analyze(files, _config) {
37
+ const findings = [];
38
+ for (const file of files) {
39
+ if (!file.path.endsWith('.php') || file.path.endsWith('.blade.php'))
40
+ continue;
41
+ const usages = findRawSqlUsages(file.content);
42
+ for (const usage of usages) {
43
+ if (usage.hasInterpolation && !usage.hasBinding) {
44
+ findings.push({
45
+ id: FINDING_INJECTION,
46
+ severity: Severity.High,
47
+ analyzer: ANALYZER_NAME,
48
+ title: `SQL injection risk in \`${usage.method}()\``,
49
+ description: `\`${usage.method}()\` is called with a string containing variable interpolation ` +
50
+ `or concatenation without parameter bindings.`,
51
+ file: file.path,
52
+ line: usage.line,
53
+ recommendation: `Use parameter bindings: \`${usage.method}('col = ?', [$value])\`.`,
54
+ cwe: 'CWE-89',
55
+ snippet: usage.snippet,
56
+ });
57
+ }
58
+ else if (!usage.hasBinding) {
59
+ findings.push({
60
+ id: FINDING_RAW_INFO,
61
+ severity: Severity.Info,
62
+ analyzer: ANALYZER_NAME,
63
+ title: `Raw SQL usage in \`${usage.method}()\` — verify safety`,
64
+ description: `\`${usage.method}()\` contains a raw SQL fragment. Ensure no user input reaches this query.`,
65
+ file: file.path,
66
+ line: usage.line,
67
+ recommendation: 'If any part of this query can be user-influenced, use parameter bindings.',
68
+ cwe: 'CWE-89',
69
+ snippet: usage.snippet,
70
+ });
71
+ }
72
+ }
73
+ }
74
+ return findings;
75
+ }
76
+ }
77
+ //# sourceMappingURL=SqlInjectionAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SqlInjectionAnalyzer.js","sourceRoot":"","sources":["../../src/analyzers/SqlInjectionAnalyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { Analyzer, Finding, HavocConfig, ParsedFile } from '../types/index.js';
2
+ export declare class XssSurfaceAnalyzer implements Analyzer {
3
+ readonly name = "XssSurfaceAnalyzer";
4
+ readonly description = "Identifies unescaped Blade output that could lead to Cross-Site Scripting (XSS)";
5
+ analyze(files: ParsedFile[], _config: HavocConfig): Promise<Finding[]>;
6
+ }
7
+ //# sourceMappingURL=XssSurfaceAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"XssSurfaceAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyzers/XssSurfaceAnalyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAY,MAAM,mBAAmB,CAAC;AAqDzF,qBAAa,kBAAmB,YAAW,QAAQ;IACjD,QAAQ,CAAC,IAAI,wBAAiB;IAC9B,QAAQ,CAAC,WAAW,qFAAqF;IAEnG,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;CAqD7E"}
@@ -0,0 +1,100 @@
1
+ import { Severity } from '../types/index.js';
2
+ const UNESCAPED_OUTPUT_PATTERN = /\{!!\s*(.+?)\s*!!\}/g;
3
+ const TRUSTED_CONTEXT_PATTERNS = [
4
+ /config\s*\(/,
5
+ /asset\s*\(/,
6
+ /url\s*\(/,
7
+ /route\s*\(/,
8
+ /__\s*\(/,
9
+ /trans\s*\(/,
10
+ ];
11
+ const USER_CONTROLLED_PATTERNS = [
12
+ /\$[a-zA-Z_][a-zA-Z0-9_]*->(?:body|content|message|description|text|html|comment|bio|about|summary)/i,
13
+ /\$(?:body|content|message|description|text|html|comment|bio|about|summary)\b/i,
14
+ /request\(\)/i,
15
+ /->input\s*\(/i,
16
+ ];
17
+ const ESCAPE_FUNCTION_PATTERNS = [
18
+ /\be\s*\(/,
19
+ /htmlspecialchars\s*\(/,
20
+ /Purifier::/,
21
+ /clean\s*\(/,
22
+ /strip_tags\s*\(/,
23
+ ];
24
+ const FINDING_HIGH = 'HAVOC-XSS-001';
25
+ const FINDING_MED = 'HAVOC-XSS-002';
26
+ const ANALYZER_NAME = 'XssSurfaceAnalyzer';
27
+ function isTrustedFilePath(path) {
28
+ return (path.includes('/mail/') ||
29
+ path.includes('/emails/') ||
30
+ path.includes('/notifications/') ||
31
+ path.includes('\\mail\\') ||
32
+ path.includes('\\emails\\') ||
33
+ path.includes('/svg/') ||
34
+ path.includes('/icons/') ||
35
+ path.endsWith('.svg.blade.php'));
36
+ }
37
+ function classifyExpression(expression, filePath) {
38
+ if (ESCAPE_FUNCTION_PATTERNS.some((re) => re.test(expression)))
39
+ return 'trusted';
40
+ if (TRUSTED_CONTEXT_PATTERNS.some((re) => re.test(expression)))
41
+ return 'trusted';
42
+ if (isTrustedFilePath(filePath))
43
+ return 'trusted';
44
+ if (USER_CONTROLLED_PATTERNS.some((re) => re.test(expression)))
45
+ return 'user-controlled';
46
+ return 'unknown';
47
+ }
48
+ export class XssSurfaceAnalyzer {
49
+ name = ANALYZER_NAME;
50
+ description = 'Identifies unescaped Blade output that could lead to Cross-Site Scripting (XSS)';
51
+ async analyze(files, _config) {
52
+ const findings = [];
53
+ for (const file of files) {
54
+ if (!file.path.endsWith('.blade.php'))
55
+ continue;
56
+ const lines = file.content.split('\n');
57
+ lines.forEach((lineText, idx) => {
58
+ const lineNum = idx + 1;
59
+ const re = new RegExp(UNESCAPED_OUTPUT_PATTERN.source, 'g');
60
+ let match;
61
+ while ((match = re.exec(lineText)) !== null) {
62
+ const expression = match[1];
63
+ const classification = classifyExpression(expression, file.path);
64
+ if (classification === 'trusted')
65
+ continue;
66
+ if (classification === 'user-controlled') {
67
+ findings.push({
68
+ id: FINDING_HIGH,
69
+ severity: Severity.High,
70
+ analyzer: ANALYZER_NAME,
71
+ title: 'Unescaped user-controlled output in Blade template',
72
+ description: `\`{!! ${expression} !!}\` outputs potentially user-controlled content without HTML escaping.`,
73
+ file: file.path,
74
+ line: lineNum,
75
+ recommendation: 'Use `{{ $variable }}` for automatic escaping.',
76
+ cwe: 'CWE-79',
77
+ snippet: lineText.trim(),
78
+ });
79
+ }
80
+ else {
81
+ findings.push({
82
+ id: FINDING_MED,
83
+ severity: Severity.Medium,
84
+ analyzer: ANALYZER_NAME,
85
+ title: 'Unescaped output in Blade template — verify safety',
86
+ description: `\`{!! ${expression} !!}\` outputs content without HTML escaping. Verify this cannot contain user HTML.`,
87
+ file: file.path,
88
+ line: lineNum,
89
+ recommendation: 'If the value could contain user input, switch to `{{ $variable }}`.',
90
+ cwe: 'CWE-79',
91
+ snippet: lineText.trim(),
92
+ });
93
+ }
94
+ }
95
+ });
96
+ }
97
+ return findings;
98
+ }
99
+ }
100
+ //# sourceMappingURL=XssSurfaceAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"XssSurfaceAnalyzer.js","sourceRoot":"","sources":["../../src/analyzers/XssSurfaceAnalyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export { AuthorizationCoverageAnalyzer } from './AuthorizationCoverageAnalyzer.js';
2
+ export { MassAssignmentAnalyzer } from './MassAssignmentAnalyzer.js';
3
+ export { XssSurfaceAnalyzer } from './XssSurfaceAnalyzer.js';
4
+ export { SqlInjectionAnalyzer } from './SqlInjectionAnalyzer.js';
5
+ export { DependencyAuditAnalyzer } from './DependencyAuditAnalyzer.js';
6
+ export { IdorAnalyzer } from './IdorAnalyzer.js';
7
+ export { CredentialExposureAnalyzer } from './CredentialExposureAnalyzer.js';
8
+ export { SessionSecurityAnalyzer } from './SessionSecurityAnalyzer.js';
9
+ export { FileUploadAnalyzer } from './FileUploadAnalyzer.js';
10
+ export { RateLimitAnalyzer } from './RateLimitAnalyzer.js';
11
+ export { EncryptionAnalyzer } from './EncryptionAnalyzer.js';
12
+ export { PrivilegeEscalationAnalyzer } from './PrivilegeEscalationAnalyzer.js';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC"}
@@ -0,0 +1,13 @@
1
+ export { AuthorizationCoverageAnalyzer } from './AuthorizationCoverageAnalyzer.js';
2
+ export { MassAssignmentAnalyzer } from './MassAssignmentAnalyzer.js';
3
+ export { XssSurfaceAnalyzer } from './XssSurfaceAnalyzer.js';
4
+ export { SqlInjectionAnalyzer } from './SqlInjectionAnalyzer.js';
5
+ export { DependencyAuditAnalyzer } from './DependencyAuditAnalyzer.js';
6
+ export { IdorAnalyzer } from './IdorAnalyzer.js';
7
+ export { CredentialExposureAnalyzer } from './CredentialExposureAnalyzer.js';
8
+ export { SessionSecurityAnalyzer } from './SessionSecurityAnalyzer.js';
9
+ export { FileUploadAnalyzer } from './FileUploadAnalyzer.js';
10
+ export { RateLimitAnalyzer } from './RateLimitAnalyzer.js';
11
+ export { EncryptionAnalyzer } from './EncryptionAnalyzer.js';
12
+ export { PrivilegeEscalationAnalyzer } from './PrivilegeEscalationAnalyzer.js';
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyzers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC"}
@@ -0,0 +1,17 @@
1
+ export * from './types/index.js';
2
+ export * from './analyzers/index.js';
3
+ export { PhpParser, PHP_FILE_PATTERNS } from './parsers/PhpParser.js';
4
+ export type { ParsedPhpFile, PhpClassInfo, PhpMethodInfo, PhpPropertyInfo } from './parsers/PhpParser.js';
5
+ export { rules } from './rules/index.js';
6
+ import { Analyzer, HavocConfig, ParsedFile, ScanResult, Severity } from './types/index.js';
7
+ export type SecurityGrade = 'A' | 'B' | 'C' | 'D' | 'F';
8
+ export declare function calculateSecurityGrade(findings: {
9
+ severity: Severity;
10
+ }[]): SecurityGrade;
11
+ export declare const DEFAULT_ANALYZERS: Analyzer[];
12
+ export declare const DEFAULT_CONFIG: HavocConfig;
13
+ export declare function scan(files: ParsedFile[], config?: HavocConfig, analyzers?: Analyzer[]): Promise<ScanResult>;
14
+ export declare function scanProject(projectPath: string, config?: HavocConfig, analyzers?: Analyzer[]): Promise<ScanResult & {
15
+ grade: SecurityGrade;
16
+ }>;
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACtE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC1G,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAMzC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAiB3F,MAAM,MAAM,aAAa,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAuBxD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE;IAAE,QAAQ,EAAE,QAAQ,CAAA;CAAE,EAAE,GAAG,aAAa,CAMxF;AAID,eAAO,MAAM,iBAAiB,EAAE,QAAQ,EAavC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,WAI5B,CAAC;AAoEF,wBAAsB,IAAI,CACxB,KAAK,EAAE,UAAU,EAAE,EACnB,MAAM,GAAE,WAA4B,EACpC,SAAS,GAAE,QAAQ,EAAsB,GACxC,OAAO,CAAC,UAAU,CAAC,CAqBrB;AAED,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,EACnB,MAAM,GAAE,WAA4B,EACpC,SAAS,GAAE,QAAQ,EAAsB,GACxC,OAAO,CAAC,UAAU,GAAG;IAAE,KAAK,EAAE,aAAa,CAAA;CAAE,CAAC,CAOhD"}