verification-layer 0.20.0 → 0.22.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 (180) hide show
  1. package/README.md +251 -615
  2. package/dist/cli.js +542 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/marketplace/index.d.ts +8 -0
  5. package/dist/marketplace/index.d.ts.map +1 -0
  6. package/dist/marketplace/index.js +7 -0
  7. package/dist/marketplace/index.js.map +1 -0
  8. package/dist/marketplace/installer.d.ts +62 -0
  9. package/dist/marketplace/installer.d.ts.map +1 -0
  10. package/dist/marketplace/installer.js +254 -0
  11. package/dist/marketplace/installer.js.map +1 -0
  12. package/dist/marketplace/registry.d.ts +52 -0
  13. package/dist/marketplace/registry.d.ts.map +1 -0
  14. package/dist/marketplace/registry.js +759 -0
  15. package/dist/marketplace/registry.js.map +1 -0
  16. package/dist/marketplace/types.d.ts +123 -0
  17. package/dist/marketplace/types.d.ts.map +1 -0
  18. package/dist/marketplace/types.js +6 -0
  19. package/dist/marketplace/types.js.map +1 -0
  20. package/dist/reporters/audit-report.d.ts.map +1 -1
  21. package/dist/reporters/audit-report.js +180 -0
  22. package/dist/reporters/audit-report.js.map +1 -1
  23. package/dist/reporters/index.d.ts.map +1 -1
  24. package/dist/reporters/index.js +2612 -5
  25. package/dist/reporters/index.js.map +1 -1
  26. package/dist/scan.d.ts.map +1 -1
  27. package/dist/scan.js +15 -1
  28. package/dist/scan.js.map +1 -1
  29. package/dist/scanners/api-security/index.d.ts +7 -0
  30. package/dist/scanners/api-security/index.d.ts.map +1 -0
  31. package/dist/scanners/api-security/index.js +139 -0
  32. package/dist/scanners/api-security/index.js.map +1 -0
  33. package/dist/scanners/api-security/index.test.d.ts +5 -0
  34. package/dist/scanners/api-security/index.test.d.ts.map +1 -0
  35. package/dist/scanners/api-security/index.test.js +360 -0
  36. package/dist/scanners/api-security/index.test.js.map +1 -0
  37. package/dist/scanners/api-security/patterns.d.ts +32 -0
  38. package/dist/scanners/api-security/patterns.d.ts.map +1 -0
  39. package/dist/scanners/api-security/patterns.js +159 -0
  40. package/dist/scanners/api-security/patterns.js.map +1 -0
  41. package/dist/scanners/authentication/index.d.ts +7 -0
  42. package/dist/scanners/authentication/index.d.ts.map +1 -0
  43. package/dist/scanners/authentication/index.js +107 -0
  44. package/dist/scanners/authentication/index.js.map +1 -0
  45. package/dist/scanners/authentication/index.test.d.ts +5 -0
  46. package/dist/scanners/authentication/index.test.d.ts.map +1 -0
  47. package/dist/scanners/authentication/index.test.js +379 -0
  48. package/dist/scanners/authentication/index.test.js.map +1 -0
  49. package/dist/scanners/authentication/patterns.d.ts +32 -0
  50. package/dist/scanners/authentication/patterns.d.ts.map +1 -0
  51. package/dist/scanners/authentication/patterns.js +133 -0
  52. package/dist/scanners/authentication/patterns.js.map +1 -0
  53. package/dist/scanners/configuration/index.d.ts +8 -0
  54. package/dist/scanners/configuration/index.d.ts.map +1 -0
  55. package/dist/scanners/configuration/index.js +87 -0
  56. package/dist/scanners/configuration/index.js.map +1 -0
  57. package/dist/scanners/configuration/index.test.d.ts +5 -0
  58. package/dist/scanners/configuration/index.test.d.ts.map +1 -0
  59. package/dist/scanners/configuration/index.test.js +344 -0
  60. package/dist/scanners/configuration/index.test.js.map +1 -0
  61. package/dist/scanners/configuration/patterns.d.ts +32 -0
  62. package/dist/scanners/configuration/patterns.d.ts.map +1 -0
  63. package/dist/scanners/configuration/patterns.js +146 -0
  64. package/dist/scanners/configuration/patterns.js.map +1 -0
  65. package/dist/scanners/credentials/index.d.ts +7 -0
  66. package/dist/scanners/credentials/index.d.ts.map +1 -0
  67. package/dist/scanners/credentials/index.js +129 -0
  68. package/dist/scanners/credentials/index.js.map +1 -0
  69. package/dist/scanners/credentials/index.test.d.ts +5 -0
  70. package/dist/scanners/credentials/index.test.d.ts.map +1 -0
  71. package/dist/scanners/credentials/index.test.js +395 -0
  72. package/dist/scanners/credentials/index.test.js.map +1 -0
  73. package/dist/scanners/credentials/patterns.d.ts +32 -0
  74. package/dist/scanners/credentials/patterns.d.ts.map +1 -0
  75. package/dist/scanners/credentials/patterns.js +140 -0
  76. package/dist/scanners/credentials/patterns.js.map +1 -0
  77. package/dist/scanners/errors/index.d.ts +8 -0
  78. package/dist/scanners/errors/index.d.ts.map +1 -0
  79. package/dist/scanners/errors/index.js +78 -0
  80. package/dist/scanners/errors/index.js.map +1 -0
  81. package/dist/scanners/errors/index.test.d.ts +5 -0
  82. package/dist/scanners/errors/index.test.d.ts.map +1 -0
  83. package/dist/scanners/errors/index.test.js +330 -0
  84. package/dist/scanners/errors/index.test.js.map +1 -0
  85. package/dist/scanners/errors/patterns.d.ts +27 -0
  86. package/dist/scanners/errors/patterns.d.ts.map +1 -0
  87. package/dist/scanners/errors/patterns.js +97 -0
  88. package/dist/scanners/errors/patterns.js.map +1 -0
  89. package/dist/scanners/hipaa2026/index.d.ts +8 -0
  90. package/dist/scanners/hipaa2026/index.d.ts.map +1 -0
  91. package/dist/scanners/hipaa2026/index.js +345 -0
  92. package/dist/scanners/hipaa2026/index.js.map +1 -0
  93. package/dist/scanners/hipaa2026/index.test.d.ts +5 -0
  94. package/dist/scanners/hipaa2026/index.test.d.ts.map +1 -0
  95. package/dist/scanners/hipaa2026/index.test.js +332 -0
  96. package/dist/scanners/hipaa2026/index.test.js.map +1 -0
  97. package/dist/scanners/hipaa2026/patterns.d.ts +57 -0
  98. package/dist/scanners/hipaa2026/patterns.d.ts.map +1 -0
  99. package/dist/scanners/hipaa2026/patterns.js +268 -0
  100. package/dist/scanners/hipaa2026/patterns.js.map +1 -0
  101. package/dist/scanners/operational/index.d.ts +7 -0
  102. package/dist/scanners/operational/index.d.ts.map +1 -0
  103. package/dist/scanners/operational/index.js +171 -0
  104. package/dist/scanners/operational/index.js.map +1 -0
  105. package/dist/scanners/operational/index.test.d.ts +5 -0
  106. package/dist/scanners/operational/index.test.d.ts.map +1 -0
  107. package/dist/scanners/operational/index.test.js +406 -0
  108. package/dist/scanners/operational/index.test.js.map +1 -0
  109. package/dist/scanners/operational/patterns.d.ts +33 -0
  110. package/dist/scanners/operational/patterns.d.ts.map +1 -0
  111. package/dist/scanners/operational/patterns.js +151 -0
  112. package/dist/scanners/operational/patterns.js.map +1 -0
  113. package/dist/scanners/rbac/index.d.ts +7 -0
  114. package/dist/scanners/rbac/index.d.ts.map +1 -0
  115. package/dist/scanners/rbac/index.js +145 -0
  116. package/dist/scanners/rbac/index.js.map +1 -0
  117. package/dist/scanners/rbac/index.test.d.ts +5 -0
  118. package/dist/scanners/rbac/index.test.d.ts.map +1 -0
  119. package/dist/scanners/rbac/index.test.js +422 -0
  120. package/dist/scanners/rbac/index.test.js.map +1 -0
  121. package/dist/scanners/rbac/patterns.d.ts +32 -0
  122. package/dist/scanners/rbac/patterns.d.ts.map +1 -0
  123. package/dist/scanners/rbac/patterns.js +124 -0
  124. package/dist/scanners/rbac/patterns.js.map +1 -0
  125. package/dist/scanners/revocation/index.d.ts +8 -0
  126. package/dist/scanners/revocation/index.d.ts.map +1 -0
  127. package/dist/scanners/revocation/index.js +83 -0
  128. package/dist/scanners/revocation/index.js.map +1 -0
  129. package/dist/scanners/revocation/index.test.d.ts +5 -0
  130. package/dist/scanners/revocation/index.test.d.ts.map +1 -0
  131. package/dist/scanners/revocation/index.test.js +332 -0
  132. package/dist/scanners/revocation/index.test.js.map +1 -0
  133. package/dist/scanners/revocation/patterns.d.ts +27 -0
  134. package/dist/scanners/revocation/patterns.d.ts.map +1 -0
  135. package/dist/scanners/revocation/patterns.js +109 -0
  136. package/dist/scanners/revocation/patterns.js.map +1 -0
  137. package/dist/scanners/sanitization/index.d.ts +8 -0
  138. package/dist/scanners/sanitization/index.d.ts.map +1 -0
  139. package/dist/scanners/sanitization/index.js +98 -0
  140. package/dist/scanners/sanitization/index.js.map +1 -0
  141. package/dist/scanners/sanitization/index.test.d.ts +5 -0
  142. package/dist/scanners/sanitization/index.test.d.ts.map +1 -0
  143. package/dist/scanners/sanitization/index.test.js +370 -0
  144. package/dist/scanners/sanitization/index.test.js.map +1 -0
  145. package/dist/scanners/sanitization/patterns.d.ts +27 -0
  146. package/dist/scanners/sanitization/patterns.d.ts.map +1 -0
  147. package/dist/scanners/sanitization/patterns.js +117 -0
  148. package/dist/scanners/sanitization/patterns.js.map +1 -0
  149. package/dist/training/certificate.d.ts +26 -0
  150. package/dist/training/certificate.d.ts.map +1 -0
  151. package/dist/training/certificate.js +92 -0
  152. package/dist/training/certificate.js.map +1 -0
  153. package/dist/training/index.d.ts +3 -0
  154. package/dist/training/index.d.ts.map +1 -0
  155. package/dist/training/index.js +243 -0
  156. package/dist/training/index.js.map +1 -0
  157. package/dist/training/modules.d.ts +13 -0
  158. package/dist/training/modules.d.ts.map +1 -0
  159. package/dist/training/modules.js +608 -0
  160. package/dist/training/modules.js.map +1 -0
  161. package/dist/training/questions.d.ts +9 -0
  162. package/dist/training/questions.d.ts.map +1 -0
  163. package/dist/training/questions.js +505 -0
  164. package/dist/training/questions.js.map +1 -0
  165. package/dist/types.d.ts +45 -0
  166. package/dist/types.d.ts.map +1 -1
  167. package/dist/utils/npm-audit.d.ts +6 -0
  168. package/dist/utils/npm-audit.d.ts.map +1 -0
  169. package/dist/utils/npm-audit.js +95 -0
  170. package/dist/utils/npm-audit.js.map +1 -0
  171. package/dist/utils/scan-history.d.ts +59 -0
  172. package/dist/utils/scan-history.d.ts.map +1 -0
  173. package/dist/utils/scan-history.js +170 -0
  174. package/dist/utils/scan-history.js.map +1 -0
  175. package/package.json +4 -1
  176. package/templates/baa-verification-letter.md +105 -0
  177. package/templates/irp.md +545 -0
  178. package/templates/notice-of-privacy-practices.md +491 -0
  179. package/templates/physical-safeguards-checklist.md +247 -0
  180. package/templates/security-officer-designation.md +237 -0
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Configuration Security Detection Patterns
3
+ * Detects insecure configuration settings and missing security controls
4
+ */
5
+ /**
6
+ * CONFIG-001: Debug/Verbose Mode Without Environment Gate
7
+ * Detects debug/verbose flags enabled without NODE_ENV check
8
+ */
9
+ export const DEBUG_WITHOUT_ENV_GATE = {
10
+ id: 'CONFIG-001',
11
+ name: 'Debug/Verbose Mode Without Environment Gate',
12
+ description: 'Debug or verbose mode enabled (debug:true, DEBUG:true, verbose:true, devTools:true) without NODE_ENV environment gate. May expose sensitive information in production.',
13
+ severity: 'high',
14
+ hipaaReference: 'NPRM Configuration Management',
15
+ patterns: [
16
+ // debug: true
17
+ /\bdebug\s*:\s*true\b/i,
18
+ // DEBUG: true (environment variable style)
19
+ /\bDEBUG\s*:\s*true\b/,
20
+ // verbose: true
21
+ /\bverbose\s*:\s*true\b/i,
22
+ // devTools: true
23
+ /\bdevTools\s*:\s*true\b/i,
24
+ // debug = true
25
+ /\bdebug\s*=\s*true\b/i,
26
+ // process.env.DEBUG = 'true'
27
+ /process\.env\.DEBUG\s*=\s*['"]true['"]/i,
28
+ ],
29
+ negativePatterns: [
30
+ // Environment checks
31
+ /NODE_ENV/i,
32
+ /process\.env\.NODE_ENV/i,
33
+ /isDevelopment/i,
34
+ /isProduction/i,
35
+ /\.env\s*===?\s*['"]development['"]/i,
36
+ /\.env\s*!==?\s*['"]production['"]/i,
37
+ // Conditional logic
38
+ /if\s*\(/i,
39
+ /\?\s*true\s*:\s*false/i,
40
+ // Test files
41
+ /\.test\./i,
42
+ /\.spec\./i,
43
+ /describe\(/i,
44
+ /it\(/i,
45
+ // Type definitions
46
+ /interface\s+/i,
47
+ /type\s+\w+\s*=/i,
48
+ // Comments (at start of line or after whitespace)
49
+ /^\s*\/\//,
50
+ /^\s*\/\*/,
51
+ ],
52
+ recommendation: 'Gate debug/verbose modes with environment checks. Example: debug: process.env.NODE_ENV === "development", or use environment variables: debug: process.env.DEBUG === "true". Never hardcode debug:true in production config.',
53
+ category: 'audit-logging',
54
+ };
55
+ /**
56
+ * CONFIG-002: Web Server Without Security Headers
57
+ * Detects web servers created without helmet or security headers middleware
58
+ */
59
+ export const SERVER_WITHOUT_SECURITY_HEADERS = {
60
+ id: 'CONFIG-002',
61
+ name: 'Web Server Without Security Headers Middleware',
62
+ description: 'Web server created (express(), createServer, new Hono, new Elysia) without helmet() or security headers middleware (CSP, X-Frame-Options, X-Content-Type-Options). Missing security headers expose app to XSS, clickjacking, and MIME sniffing attacks.',
63
+ severity: 'medium',
64
+ hipaaReference: 'NPRM Configuration Management',
65
+ patterns: [
66
+ // Express app creation
67
+ /(?:const|let|var)\s+\w+\s*=\s*express\s*\(\s*\)/i,
68
+ // HTTP server creation
69
+ /(?:http|https)\.createServer\s*\(/i,
70
+ // Hono
71
+ /new\s+Hono\s*\(/i,
72
+ // Elysia
73
+ /new\s+Elysia\s*\(/i,
74
+ // Fastify
75
+ /fastify\s*\(\s*\{/i,
76
+ // Koa
77
+ /new\s+Koa\s*\(/i,
78
+ ],
79
+ negativePatterns: [
80
+ // Helmet middleware
81
+ /helmet\s*\(/i,
82
+ /app\.use\s*\(\s*helmet/i,
83
+ // Security headers
84
+ /Content-Security-Policy/i,
85
+ /X-Frame-Options/i,
86
+ /X-Content-Type-Options/i,
87
+ /Strict-Transport-Security/i,
88
+ /X-XSS-Protection/i,
89
+ // Header setting methods
90
+ /setHeader\s*\(/i,
91
+ /\.set\s*\(\s*['"]X-Frame-Options['"]/i,
92
+ /\.header\s*\(/i,
93
+ // Security middleware
94
+ /cors\s*\(/i,
95
+ /compression\s*\(/i,
96
+ // Configuration objects with security
97
+ /security/i,
98
+ ],
99
+ recommendation: 'Add helmet middleware for Express: app.use(helmet()), or set security headers manually: res.setHeader("X-Frame-Options", "DENY"); res.setHeader("X-Content-Type-Options", "nosniff"); res.setHeader("Content-Security-Policy", "default-src \'self\'"). Use helmet for comprehensive security headers.',
100
+ category: 'audit-logging',
101
+ };
102
+ /**
103
+ * CONFIG-003: Test Framework Imports in Production Code
104
+ * Detects test framework imports in non-test files
105
+ */
106
+ export const TEST_IMPORTS_IN_PRODUCTION = {
107
+ id: 'CONFIG-003',
108
+ name: 'Test Framework Imports in Production Code',
109
+ description: 'Test framework imports (jest, vitest, mocha, chai, faker, cypress) found in production code (non-test files). Test frameworks should only be imported in test files (*.test.*, *.spec.*).',
110
+ severity: 'low',
111
+ hipaaReference: 'NPRM Configuration Management',
112
+ patterns: [
113
+ // Jest
114
+ /import\s+.*?from\s+['"]@?jest/i,
115
+ /require\s*\(\s*['"]@?jest/i,
116
+ // Vitest
117
+ /import\s+.*?from\s+['"]vitest['"]/i,
118
+ /require\s*\(\s*['"]vitest['"]/i,
119
+ // Mocha
120
+ /import\s+.*?from\s+['"]mocha['"]/i,
121
+ /require\s*\(\s*['"]mocha['"]/i,
122
+ // Chai
123
+ /import\s+.*?from\s+['"]chai['"]/i,
124
+ /require\s*\(\s*['"]chai['"]/i,
125
+ // Faker
126
+ /import\s+.*?from\s+['"]@?faker/i,
127
+ /require\s*\(\s*['"]@?faker/i,
128
+ // Cypress
129
+ /import\s+.*?from\s+['"]cypress['"]/i,
130
+ /require\s*\(\s*['"]cypress['"]/i,
131
+ // Testing Library
132
+ /import\s+.*?from\s+['"]@testing-library/i,
133
+ /require\s*\(\s*['"]@testing-library/i,
134
+ ],
135
+ negativePatterns: [
136
+ // This pattern will be checked in the scanner by filename, not content
137
+ ],
138
+ recommendation: 'Remove test framework imports from production code. Test frameworks should only be imported in test files (*.test.ts, *.spec.js, etc.). Move test utilities to separate test helper files.',
139
+ category: 'audit-logging',
140
+ };
141
+ export const ALL_CONFIGURATION_PATTERNS = [
142
+ DEBUG_WITHOUT_ENV_GATE,
143
+ SERVER_WITHOUT_SECURITY_HEADERS,
144
+ TEST_IMPORTS_IN_PRODUCTION,
145
+ ];
146
+ //# sourceMappingURL=patterns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../../src/scanners/configuration/patterns.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAyB;IAC1D,EAAE,EAAE,YAAY;IAChB,IAAI,EAAE,6CAA6C;IACnD,WAAW,EACT,wKAAwK;IAC1K,QAAQ,EAAE,MAAM;IAChB,cAAc,EAAE,+BAA+B;IAC/C,QAAQ,EAAE;QACR,cAAc;QACd,uBAAuB;QAEvB,2CAA2C;QAC3C,sBAAsB;QAEtB,gBAAgB;QAChB,yBAAyB;QAEzB,iBAAiB;QACjB,0BAA0B;QAE1B,eAAe;QACf,uBAAuB;QAEvB,6BAA6B;QAC7B,yCAAyC;KAC1C;IACD,gBAAgB,EAAE;QAChB,qBAAqB;QACrB,WAAW;QACX,yBAAyB;QACzB,gBAAgB;QAChB,eAAe;QACf,qCAAqC;QACrC,oCAAoC;QAEpC,oBAAoB;QACpB,UAAU;QACV,wBAAwB;QAExB,aAAa;QACb,WAAW;QACX,WAAW;QACX,aAAa;QACb,OAAO;QAEP,mBAAmB;QACnB,eAAe;QACf,iBAAiB;QAEjB,kDAAkD;QAClD,UAAU;QACV,UAAU;KACX;IACD,cAAc,EACZ,8NAA8N;IAChO,QAAQ,EAAE,eAAe;CAC1B,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAyB;IACnE,EAAE,EAAE,YAAY;IAChB,IAAI,EAAE,gDAAgD;IACtD,WAAW,EACT,yPAAyP;IAC3P,QAAQ,EAAE,QAAQ;IAClB,cAAc,EAAE,+BAA+B;IAC/C,QAAQ,EAAE;QACR,uBAAuB;QACvB,kDAAkD;QAElD,uBAAuB;QACvB,oCAAoC;QAEpC,OAAO;QACP,kBAAkB;QAElB,SAAS;QACT,oBAAoB;QAEpB,UAAU;QACV,oBAAoB;QAEpB,MAAM;QACN,iBAAiB;KAClB;IACD,gBAAgB,EAAE;QAChB,oBAAoB;QACpB,cAAc;QACd,yBAAyB;QAEzB,mBAAmB;QACnB,0BAA0B;QAC1B,kBAAkB;QAClB,yBAAyB;QACzB,4BAA4B;QAC5B,mBAAmB;QAEnB,yBAAyB;QACzB,iBAAiB;QACjB,uCAAuC;QACvC,gBAAgB;QAEhB,sBAAsB;QACtB,YAAY;QACZ,mBAAmB;QAEnB,sCAAsC;QACtC,WAAW;KACZ;IACD,cAAc,EACZ,wSAAwS;IAC1S,QAAQ,EAAE,eAAe;CAC1B,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAyB;IAC9D,EAAE,EAAE,YAAY;IAChB,IAAI,EAAE,2CAA2C;IACjD,WAAW,EACT,2LAA2L;IAC7L,QAAQ,EAAE,KAAK;IACf,cAAc,EAAE,+BAA+B;IAC/C,QAAQ,EAAE;QACR,OAAO;QACP,gCAAgC;QAChC,4BAA4B;QAE5B,SAAS;QACT,oCAAoC;QACpC,gCAAgC;QAEhC,QAAQ;QACR,mCAAmC;QACnC,+BAA+B;QAE/B,OAAO;QACP,kCAAkC;QAClC,8BAA8B;QAE9B,QAAQ;QACR,iCAAiC;QACjC,6BAA6B;QAE7B,UAAU;QACV,qCAAqC;QACrC,iCAAiC;QAEjC,kBAAkB;QAClB,0CAA0C;QAC1C,sCAAsC;KACvC;IACD,gBAAgB,EAAE;IAChB,uEAAuE;KACxE;IACD,cAAc,EACZ,4LAA4L;IAC9L,QAAQ,EAAE,eAAe;CAC1B,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAA2B;IAChE,sBAAsB;IACtB,+BAA+B;IAC/B,0BAA0B;CAC3B,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Credential Security Scanner
3
+ * Detects weak password hashing, hardcoded credentials, and exposed secrets
4
+ */
5
+ import type { Scanner } from '../../types.js';
6
+ export declare const credentialsScanner: Scanner;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/scanners/credentials/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAwB,MAAM,gBAAgB,CAAC;AAMpE,eAAO,MAAM,kBAAkB,EAAE,OAkGhC,CAAC"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Credential Security Scanner
3
+ * Detects weak password hashing, hardcoded credentials, and exposed secrets
4
+ */
5
+ import * as fs from 'fs/promises';
6
+ import { ALL_CREDENTIAL_PATTERNS, } from './patterns.js';
7
+ export const credentialsScanner = {
8
+ name: 'Credential Security Scanner',
9
+ category: 'encryption',
10
+ async scan(files, options) {
11
+ const findings = [];
12
+ // Filter to code and config files
13
+ const codeFiles = files.filter((f) => /\.(js|ts|jsx|tsx|py|java|go|rb|php|cs|env|yml|yaml|json)$/i.test(f));
14
+ for (const file of codeFiles) {
15
+ try {
16
+ const content = await fs.readFile(file, 'utf-8');
17
+ const lines = content.split('\n');
18
+ for (const pattern of ALL_CREDENTIAL_PATTERNS) {
19
+ // Special handling for CRED-001 (weak password hashing)
20
+ if (pattern.id === 'CRED-001') {
21
+ await scanWeakPasswordHashing(file, content, lines, pattern, findings);
22
+ continue;
23
+ }
24
+ // Standard pattern matching for CRED-002 and CRED-003
25
+ for (let i = 0; i < lines.length; i++) {
26
+ const line = lines[i];
27
+ const lineNumber = i + 1;
28
+ // Skip comments and empty lines
29
+ if (/^\s*(?:\/\/|#|\/\*|\*|$)/.test(line))
30
+ continue;
31
+ // Check if line matches violation pattern
32
+ const matched = pattern.patterns.some((p) => p.test(line));
33
+ if (!matched)
34
+ continue;
35
+ // Check if negative patterns indicate safe usage
36
+ const isSafe = pattern.negativePatterns?.some((p) => {
37
+ // Check current line for safe indicators
38
+ if (p.test(line))
39
+ return true;
40
+ // For CRED-002, check if it's an env var or placeholder
41
+ if (pattern.id === 'CRED-002') {
42
+ // Extract the value being assigned
43
+ const valueMatch = line.match(/[:=]\s*['"`]([^'"`]+)['"`]/);
44
+ if (valueMatch) {
45
+ const value = valueMatch[1];
46
+ // Check if value looks like a placeholder
47
+ if (/^(?:your|my|the|a|an|test|example|demo|sample|placeholder|xxx|changeme|replace|todo)/i.test(value)) {
48
+ return true;
49
+ }
50
+ // Check if value is too short or generic
51
+ if (value.length < 8 ||
52
+ /^(?:12345|qwerty|password|admin|test)/i.test(value)) {
53
+ return true;
54
+ }
55
+ }
56
+ }
57
+ return false;
58
+ });
59
+ if (isSafe)
60
+ continue;
61
+ // Create finding
62
+ findings.push({
63
+ id: pattern.id,
64
+ category: 'encryption',
65
+ severity: pattern.severity,
66
+ title: pattern.name,
67
+ description: `${pattern.description}\n\nCode: ${line.trim()}`,
68
+ file: file,
69
+ line: lineNumber,
70
+ recommendation: pattern.recommendation,
71
+ hipaaReference: pattern.hipaaReference,
72
+ confidence: 'high',
73
+ });
74
+ }
75
+ }
76
+ }
77
+ catch (error) {
78
+ // Skip files that can't be read
79
+ }
80
+ }
81
+ return findings;
82
+ },
83
+ };
84
+ /**
85
+ * Scan for weak password hashing algorithms
86
+ */
87
+ async function scanWeakPasswordHashing(file, content, lines, pattern, findings) {
88
+ for (let i = 0; i < lines.length; i++) {
89
+ const line = lines[i];
90
+ const lineNumber = i + 1;
91
+ // Skip comments
92
+ if (/^\s*(?:\/\/|#|\/\*|\*)/.test(line))
93
+ continue;
94
+ // Check if line contains weak hashing
95
+ const hasWeakHash = pattern.patterns.some((p) => p.test(line));
96
+ if (!hasWeakHash)
97
+ continue;
98
+ // Check surrounding context (5 lines before and after) for password-related code
99
+ const contextStart = Math.max(0, i - 5);
100
+ const contextEnd = Math.min(lines.length, i + 6);
101
+ const context = lines.slice(contextStart, contextEnd).join('\n');
102
+ // Check if this is related to password hashing
103
+ const isPasswordRelated = /password|passwd|pwd|credential|auth/i.test(context);
104
+ // Check if secure algorithms are present (indicates awareness/migration)
105
+ const hasSecureAlgo = pattern.negativePatterns?.some((p) => p.test(context));
106
+ if (hasSecureAlgo)
107
+ continue;
108
+ // Check if it's for non-password use (checksums, file hashing)
109
+ const isNonPasswordUse = pattern.negativePatterns?.some((p) => p.test(line) && /checksum|file|integrity/i.test(p.source));
110
+ if (isNonPasswordUse)
111
+ continue;
112
+ // Only flag if it's likely password-related
113
+ if (isPasswordRelated) {
114
+ findings.push({
115
+ id: pattern.id,
116
+ category: 'encryption',
117
+ severity: pattern.severity,
118
+ title: pattern.name,
119
+ description: `${pattern.description}\n\nCode: ${line.trim()}\n\nWeak hashing algorithm detected in password-related code.`,
120
+ file: file,
121
+ line: lineNumber,
122
+ recommendation: pattern.recommendation,
123
+ hipaaReference: pattern.hipaaReference,
124
+ confidence: 'high',
125
+ });
126
+ }
127
+ }
128
+ }
129
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/scanners/credentials/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for Credential Security Scanner
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../src/scanners/credentials/index.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}