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,78 @@
1
+ /**
2
+ * Error Handling Security Scanner
3
+ * Detects unsafe error responses and PHI in error logs
4
+ */
5
+ import * as fs from 'fs/promises';
6
+ import { ALL_ERROR_PATTERNS } from './patterns.js';
7
+ export const errorsScanner = {
8
+ name: 'Error Handling Security Scanner',
9
+ category: 'audit-logging',
10
+ async scan(files, options) {
11
+ const findings = [];
12
+ // Filter to code files
13
+ const codeFiles = files.filter((f) => /\.(ts|tsx|js|jsx)$/.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
+ // Check if this is a test file (check filename)
19
+ const isTestFile = /\.(?:test|spec)\.[jt]sx?$/.test(file);
20
+ for (let i = 0; i < lines.length; i++) {
21
+ const line = lines[i];
22
+ const lineNumber = i + 1;
23
+ // Skip empty lines
24
+ if (/^\s*$/.test(line))
25
+ continue;
26
+ // Scan each pattern
27
+ for (const pattern of ALL_ERROR_PATTERNS) {
28
+ // Check if line matches any pattern
29
+ const matched = pattern.patterns.some((regex) => regex.test(line));
30
+ if (!matched)
31
+ continue;
32
+ // For ERROR-002, skip test files
33
+ if (pattern.id === 'ERROR-002' && isTestFile)
34
+ continue;
35
+ // Get surrounding context (5 lines before and after)
36
+ const contextStart = Math.max(0, i - 5);
37
+ const contextEnd = Math.min(lines.length, i + 6);
38
+ const context = lines.slice(contextStart, contextEnd).join('\n');
39
+ // Check negative patterns (safe usage indicators)
40
+ // For ERROR-001, only check development env in context, rest in current line
41
+ // For ERROR-002, check redaction/masking in context, test file in filename
42
+ const isSafe = pattern.negativePatterns?.some((regex) => {
43
+ const patternStr = regex.source;
44
+ // Check development environment and redaction/masking in context
45
+ if (/NODE_ENV|isDevelopment|redact|mask|sanitize|obfuscate/i.test(patternStr)) {
46
+ return regex.test(context);
47
+ }
48
+ // All other patterns check current line only
49
+ return regex.test(line);
50
+ });
51
+ if (isSafe)
52
+ continue;
53
+ // Create finding
54
+ const finding = {
55
+ id: pattern.id,
56
+ category: pattern.category,
57
+ severity: pattern.severity,
58
+ title: pattern.name,
59
+ description: `${pattern.description}\n\nCode: ${line.trim()}`,
60
+ file: file,
61
+ line: lineNumber,
62
+ recommendation: pattern.recommendation,
63
+ hipaaReference: pattern.hipaaReference,
64
+ confidence: 'high',
65
+ };
66
+ findings.push(finding);
67
+ }
68
+ }
69
+ }
70
+ catch (error) {
71
+ // Skip files that can't be read
72
+ }
73
+ }
74
+ return findings;
75
+ },
76
+ };
77
+ export default errorsScanner;
78
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/scanners/errors/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Error Handling Security Scanner Tests
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/errors/index.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,330 @@
1
+ /**
2
+ * Error Handling Security Scanner Tests
3
+ */
4
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
5
+ import { errorsScanner } from './index.js';
6
+ import * as fs from 'fs/promises';
7
+ import * as path from 'path';
8
+ import * as os from 'os';
9
+ describe('Error Handling Security Scanner', () => {
10
+ let tempDir = '';
11
+ let testFiles = [];
12
+ beforeEach(async () => {
13
+ tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'errors-test-'));
14
+ });
15
+ afterEach(async () => {
16
+ // Cleanup
17
+ for (const file of testFiles) {
18
+ try {
19
+ await fs.unlink(file);
20
+ }
21
+ catch {
22
+ // Ignore
23
+ }
24
+ }
25
+ try {
26
+ await fs.rm(tempDir, { recursive: true, force: true });
27
+ }
28
+ catch {
29
+ // Ignore
30
+ }
31
+ testFiles = [];
32
+ });
33
+ async function createTestFile(filename, content) {
34
+ const filePath = path.join(tempDir, filename);
35
+ await fs.writeFile(filePath, content, 'utf-8');
36
+ testFiles.push(filePath);
37
+ return filePath;
38
+ }
39
+ const scanOptions = {
40
+ path: tempDir,
41
+ };
42
+ describe('ERROR-001: Unsanitized Error Details Sent to User', () => {
43
+ it('should detect error.stack in res.send', async () => {
44
+ const file = await createTestFile('error-stack.ts', `
45
+ // VIOLATION ERROR-001: Sending error.stack to user
46
+ app.get('/api/data', (req, res) => {
47
+ try {
48
+ processData();
49
+ } catch (error) {
50
+ res.send(error.stack);
51
+ }
52
+ });
53
+ `);
54
+ const findings = await errorsScanner.scan([file], scanOptions);
55
+ expect(findings.length).toBeGreaterThan(0);
56
+ expect(findings.some((f) => f.id === 'ERROR-001')).toBe(true);
57
+ });
58
+ it('should detect error.stack in res.json', async () => {
59
+ const file = await createTestFile('error-json.ts', `
60
+ // VIOLATION ERROR-001: JSON with error.stack
61
+ export async function handler(req, res) {
62
+ try {
63
+ await fetchData();
64
+ } catch (err) {
65
+ res.json({ error: err.stack });
66
+ }
67
+ }
68
+ `);
69
+ const findings = await errorsScanner.scan([file], scanOptions);
70
+ expect(findings.some((f) => f.id === 'ERROR-001')).toBe(true);
71
+ });
72
+ it('should detect error.message in res.send', async () => {
73
+ const file = await createTestFile('error-message.ts', `
74
+ // VIOLATION ERROR-001: Sending error.message
75
+ catch (error) {
76
+ res.send(error.message);
77
+ }
78
+ `);
79
+ const findings = await errorsScanner.scan([file], scanOptions);
80
+ expect(findings.some((f) => f.id === 'ERROR-001')).toBe(true);
81
+ });
82
+ it('should detect error object sent directly', async () => {
83
+ const file = await createTestFile('error-direct.ts', `
84
+ // VIOLATION ERROR-001: Sending full error object
85
+ catch (err) {
86
+ return res.json(err);
87
+ }
88
+ `);
89
+ const findings = await errorsScanner.scan([file], scanOptions);
90
+ expect(findings.some((f) => f.id === 'ERROR-001')).toBe(true);
91
+ });
92
+ it('should detect error in catch block response', async () => {
93
+ const file = await createTestFile('catch-error.ts', `
94
+ // VIOLATION ERROR-001: Catch block sends error
95
+ try {
96
+ doSomething();
97
+ } catch (error) { res.send(error); }
98
+ `);
99
+ const findings = await errorsScanner.scan([file], scanOptions);
100
+ expect(findings.some((f) => f.id === 'ERROR-001')).toBe(true);
101
+ });
102
+ it('should detect next(error) pattern', async () => {
103
+ const file = await createTestFile('next-error.ts', `
104
+ // VIOLATION ERROR-001: Passing error to next
105
+ catch (error) {
106
+ next(error);
107
+ }
108
+ `);
109
+ const findings = await errorsScanner.scan([file], scanOptions);
110
+ expect(findings.some((f) => f.id === 'ERROR-001')).toBe(true);
111
+ });
112
+ it('should NOT flag sanitized errors', async () => {
113
+ const file = await createTestFile('sanitized.ts', `
114
+ // SECURE: Sanitized error message
115
+ catch (error) {
116
+ const sanitizedError = sanitizeError(error);
117
+ res.send(sanitizedError);
118
+ }
119
+ `);
120
+ const findings = await errorsScanner.scan([file], scanOptions);
121
+ const error001 = findings.filter((f) => f.id === 'ERROR-001');
122
+ expect(error001.length).toBe(0);
123
+ });
124
+ it('should NOT flag generic error messages', async () => {
125
+ const file = await createTestFile('generic.ts', `
126
+ // SECURE: Generic error message
127
+ catch (error) {
128
+ res.status(500).json({ error: "An error occurred" });
129
+ }
130
+ `);
131
+ const findings = await errorsScanner.scan([file], scanOptions);
132
+ const error001 = findings.filter((f) => f.id === 'ERROR-001');
133
+ expect(error001.length).toBe(0);
134
+ });
135
+ it('should NOT flag console logging (not sent to user)', async () => {
136
+ const file = await createTestFile('console.ts', `
137
+ // SECURE: Logging error.stack (not sending to user)
138
+ catch (error) {
139
+ console.error(error.stack);
140
+ res.status(500).json({ error: "Internal server error" });
141
+ }
142
+ `);
143
+ const findings = await errorsScanner.scan([file], scanOptions);
144
+ const error001 = findings.filter((f) => f.id === 'ERROR-001');
145
+ expect(error001.length).toBe(0);
146
+ });
147
+ it('should NOT flag development environment checks', async () => {
148
+ const file = await createTestFile('dev-env.ts', `
149
+ // SECURE: Development mode only
150
+ catch (error) {
151
+ if (process.env.NODE_ENV === 'development') {
152
+ res.send(error.stack);
153
+ }
154
+ }
155
+ `);
156
+ const findings = await errorsScanner.scan([file], scanOptions);
157
+ const error001 = findings.filter((f) => f.id === 'ERROR-001');
158
+ expect(error001.length).toBe(0);
159
+ });
160
+ });
161
+ describe('ERROR-002: PHI in Error Logs or Thrown Errors', () => {
162
+ it('should detect patient data in console.log', async () => {
163
+ const file = await createTestFile('console-patient.ts', `
164
+ // VIOLATION ERROR-002: PHI in console.log
165
+ function processPatient(patient) {
166
+ console.log('Processing patient:', patient);
167
+ }
168
+ `);
169
+ const findings = await errorsScanner.scan([file], scanOptions);
170
+ expect(findings.some((f) => f.id === 'ERROR-002')).toBe(true);
171
+ });
172
+ it('should detect SSN in console.error', async () => {
173
+ const file = await createTestFile('console-ssn.ts', `
174
+ // VIOLATION ERROR-002: SSN in error log
175
+ if (!validSSN(ssn)) {
176
+ console.error('Invalid SSN:', ssn);
177
+ }
178
+ `);
179
+ const findings = await errorsScanner.scan([file], scanOptions);
180
+ expect(findings.some((f) => f.id === 'ERROR-002')).toBe(true);
181
+ });
182
+ it('should detect DOB in logger.warn', async () => {
183
+ const file = await createTestFile('logger-dob.ts', `
184
+ // VIOLATION ERROR-002: DOB in logger
185
+ logger.warn('Missing DOB for patient:', { dob: patient.dob });
186
+ `);
187
+ const findings = await errorsScanner.scan([file], scanOptions);
188
+ expect(findings.some((f) => f.id === 'ERROR-002')).toBe(true);
189
+ });
190
+ it('should detect MRN in throw Error', async () => {
191
+ const file = await createTestFile('throw-mrn.ts', `
192
+ // VIOLATION ERROR-002: MRN in thrown error
193
+ if (!patient) {
194
+ throw new Error('Patient not found with MRN: ' + mrn);
195
+ }
196
+ `);
197
+ const findings = await errorsScanner.scan([file], scanOptions);
198
+ expect(findings.some((f) => f.id === 'ERROR-002')).toBe(true);
199
+ });
200
+ it('should detect diagnosis in logger.error', async () => {
201
+ const file = await createTestFile('logger-diagnosis.ts', `
202
+ // VIOLATION ERROR-002: Diagnosis in error log
203
+ logger.error('Failed to save diagnosis:', diagnosis);
204
+ `);
205
+ const findings = await errorsScanner.scan([file], scanOptions);
206
+ expect(findings.some((f) => f.id === 'ERROR-002')).toBe(true);
207
+ });
208
+ it('should detect medication in console.warn', async () => {
209
+ const file = await createTestFile('console-medication.ts', `
210
+ // VIOLATION ERROR-002: Medication in warning
211
+ console.warn('Discontinued medication:', medication);
212
+ `);
213
+ const findings = await errorsScanner.scan([file], scanOptions);
214
+ expect(findings.some((f) => f.id === 'ERROR-002')).toBe(true);
215
+ });
216
+ it('should detect health_record in logger', async () => {
217
+ const file = await createTestFile('logger-health.ts', `
218
+ // VIOLATION ERROR-002: Health record in log
219
+ logger.info('Updating health_record:', health_record);
220
+ `);
221
+ const findings = await errorsScanner.scan([file], scanOptions);
222
+ expect(findings.some((f) => f.id === 'ERROR-002')).toBe(true);
223
+ });
224
+ it('should detect patientData in console', async () => {
225
+ const file = await createTestFile('patient-data.ts', `
226
+ // VIOLATION ERROR-002: Patient data object
227
+ console.debug('Patient data:', patientData);
228
+ `);
229
+ const findings = await errorsScanner.scan([file], scanOptions);
230
+ expect(findings.some((f) => f.id === 'ERROR-002')).toBe(true);
231
+ });
232
+ it('should NOT flag redacted PHI', async () => {
233
+ const file = await createTestFile('redacted.ts', `
234
+ // SECURE: Redacted patient data
235
+ logger.error('Error processing patient:', {
236
+ patientId: redact(patient.id)
237
+ });
238
+ `);
239
+ const findings = await errorsScanner.scan([file], scanOptions);
240
+ const error002 = findings.filter((f) => f.id === 'ERROR-002');
241
+ expect(error002.length).toBe(0);
242
+ });
243
+ it('should NOT flag masked data', async () => {
244
+ const file = await createTestFile('masked.ts', `
245
+ // SECURE: Masked SSN
246
+ console.log('SSN:', maskSsn(patient.ssn));
247
+ `);
248
+ const findings = await errorsScanner.scan([file], scanOptions);
249
+ const error002 = findings.filter((f) => f.id === 'ERROR-002');
250
+ expect(error002.length).toBe(0);
251
+ });
252
+ it('should NOT flag generic patient messages', async () => {
253
+ const file = await createTestFile('generic-message.ts', `
254
+ // SECURE: Generic message without PHI
255
+ if (!patient) {
256
+ throw new Error("Patient not found");
257
+ }
258
+ `);
259
+ const findings = await errorsScanner.scan([file], scanOptions);
260
+ const error002 = findings.filter((f) => f.id === 'ERROR-002');
261
+ expect(error002.length).toBe(0);
262
+ });
263
+ it('should NOT flag patient ID only', async () => {
264
+ const file = await createTestFile('patient-id.ts', `
265
+ // SECURE: Patient ID is allowed (not full PHI)
266
+ logger.error('Error for patient_id:', patient_id);
267
+ `);
268
+ const findings = await errorsScanner.scan([file], scanOptions);
269
+ const error002 = findings.filter((f) => f.id === 'ERROR-002');
270
+ expect(error002.length).toBe(0);
271
+ });
272
+ it('should NOT flag test files', async () => {
273
+ const file = await createTestFile('patient.test.ts', `
274
+ // SECURE: Test file
275
+ describe('patient tests', () => {
276
+ it('should process patient', () => {
277
+ console.log(patient);
278
+ });
279
+ });
280
+ `);
281
+ const findings = await errorsScanner.scan([file], scanOptions);
282
+ const error002 = findings.filter((f) => f.id === 'ERROR-002');
283
+ expect(error002.length).toBe(0);
284
+ });
285
+ });
286
+ describe('Combined violations', () => {
287
+ it('should detect multiple ERROR-001 and ERROR-002 violations in same file', async () => {
288
+ const file = await createTestFile('combined.ts', `
289
+ // Multiple violations
290
+ export async function handler(req, res) {
291
+ try {
292
+ const patient = await getPatient(req.params.id);
293
+ console.log('Processing patient:', patient); // ERROR-002
294
+ processHealthRecord(patient);
295
+ } catch (error) {
296
+ logger.error('Patient error:', patient); // ERROR-002
297
+ res.send(error.stack); // ERROR-001
298
+ }
299
+ }
300
+ `);
301
+ const findings = await errorsScanner.scan([file], scanOptions);
302
+ expect(findings.some((f) => f.id === 'ERROR-001')).toBe(true);
303
+ expect(findings.some((f) => f.id === 'ERROR-002')).toBe(true);
304
+ expect(findings.length).toBeGreaterThanOrEqual(2);
305
+ });
306
+ });
307
+ it('should provide correct HIPAA references', async () => {
308
+ const file = await createTestFile('hipaa-refs.ts', `
309
+ res.send(error.stack); // ERROR-001
310
+ console.log(patient); // ERROR-002
311
+ `);
312
+ const findings = await errorsScanner.scan([file], scanOptions);
313
+ const error001 = findings.find((f) => f.id === 'ERROR-001');
314
+ const error002 = findings.find((f) => f.id === 'ERROR-002');
315
+ expect(error001?.hipaaReference).toContain('164.312(b)');
316
+ expect(error002?.hipaaReference).toContain('164.312(c)');
317
+ });
318
+ it('should have correct severity levels', async () => {
319
+ const file = await createTestFile('severity.ts', `
320
+ res.json(error); // ERROR-001 (high)
321
+ console.log(patient.ssn); // ERROR-002 (critical)
322
+ `);
323
+ const findings = await errorsScanner.scan([file], scanOptions);
324
+ const error001 = findings.find((f) => f.id === 'ERROR-001');
325
+ const error002 = findings.find((f) => f.id === 'ERROR-002');
326
+ expect(error001?.severity).toBe('high');
327
+ expect(error002?.severity).toBe('critical');
328
+ });
329
+ });
330
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../src/scanners/errors/index.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Error Handling Security Detection Patterns
3
+ * Detects unsafe error responses and PHI in error logs
4
+ */
5
+ export interface ErrorPattern {
6
+ id: string;
7
+ name: string;
8
+ description: string;
9
+ severity: 'critical' | 'high' | 'medium';
10
+ hipaaReference: string;
11
+ patterns: RegExp[];
12
+ negativePatterns?: RegExp[];
13
+ recommendation: string;
14
+ category: string;
15
+ }
16
+ /**
17
+ * ERROR-001: Unsanitized Error Details Sent to User
18
+ * Detects error.stack or error.message sent directly in responses
19
+ */
20
+ export declare const UNSANITIZED_ERROR_RESPONSE: ErrorPattern;
21
+ /**
22
+ * ERROR-002: PHI in Error Logs/Throws
23
+ * Detects PHI data in console.log, logger, or throw Error
24
+ */
25
+ export declare const PHI_IN_ERROR_LOGS: ErrorPattern;
26
+ export declare const ALL_ERROR_PATTERNS: ErrorPattern[];
27
+ //# sourceMappingURL=patterns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../../src/scanners/errors/patterns.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;IACzC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EAAE,YAkDxC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,YAiD/B,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,YAAY,EAG5C,CAAC"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Error Handling Security Detection Patterns
3
+ * Detects unsafe error responses and PHI in error logs
4
+ */
5
+ /**
6
+ * ERROR-001: Unsanitized Error Details Sent to User
7
+ * Detects error.stack or error.message sent directly in responses
8
+ */
9
+ export const UNSANITIZED_ERROR_RESPONSE = {
10
+ id: 'ERROR-001',
11
+ name: 'Unsanitized Error Details Sent to User',
12
+ description: 'Response sends error.stack or error.message directly to user without sanitization, potentially exposing sensitive system information',
13
+ severity: 'high',
14
+ hipaaReference: '45 CFR §164.312(b) - Audit Controls',
15
+ patterns: [
16
+ // res.send/json with error.stack
17
+ /res\.(?:send|json)\s*\([^)]*err(?:or)?\.stack/i,
18
+ // res.send/json with error.message
19
+ /res\.(?:send|json)\s*\([^)]*err(?:or)?\.message/i,
20
+ // res.send/json with error object directly (just the variable)
21
+ /res\.(?:send|json)\s*\(\s*err(?:or)?\s*\)/i,
22
+ // return error object directly
23
+ /return.*?res\.(?:send|json)\s*\(\s*err(?:or)?\s*\)/i,
24
+ // Response with error details
25
+ /response\.(?:send|json)\s*\([^)]*err(?:or)?\.(?:stack|message)/i,
26
+ // Next.js/Express error handlers
27
+ /next\s*\(\s*err(?:or)?\s*\)/i,
28
+ // throw error with stack
29
+ /throw.*?err(?:or)?\.stack/i,
30
+ ],
31
+ negativePatterns: [
32
+ // Sanitized error messages
33
+ /sanitize/i,
34
+ /safe.*?error/i,
35
+ /filterError/i,
36
+ // Generic user-friendly messages
37
+ /['"](?:An error occurred|Internal server error|Something went wrong)/i,
38
+ // Logging (not sending to user)
39
+ /console\./i,
40
+ /logger\./i,
41
+ /log\(/i,
42
+ // Development environment checks
43
+ /process\.env\.NODE_ENV\s*===?\s*['"]development['"]/i,
44
+ /isDevelopment/i,
45
+ ],
46
+ recommendation: 'Never send error.stack or error.message directly to users. Use generic error messages for production. Example: res.status(500).json({ error: "An error occurred" }). Log detailed errors server-side only.',
47
+ category: 'audit-logging',
48
+ };
49
+ /**
50
+ * ERROR-002: PHI in Error Logs/Throws
51
+ * Detects PHI data in console.log, logger, or throw Error
52
+ */
53
+ export const PHI_IN_ERROR_LOGS = {
54
+ id: 'ERROR-002',
55
+ name: 'PHI Data in Error Logs or Thrown Errors',
56
+ description: 'Protected Health Information (patient, ssn, dob, mrn, diagnosis, medication, healthRecord) exposed in console logs, logger, or thrown errors',
57
+ severity: 'critical',
58
+ hipaaReference: '45 CFR §164.312(c) - Integrity Controls',
59
+ patterns: [
60
+ // console.* with PHI
61
+ /console\.(?:log|error|warn|info|debug)\s*\([^)]*(?:patient|ssn|dob|mrn|diagnosis|medication|health[-_]?record)/i,
62
+ // logger.* with PHI
63
+ /logger\.(?:error|warn|info|debug|log)\s*\([^)]*(?:patient|ssn|dob|mrn|diagnosis|medication|health[-_]?record)/i,
64
+ // throw Error with PHI
65
+ /throw\s+(?:new\s+)?Error\s*\([^)]*(?:patient|ssn|dob|mrn|diagnosis|medication|health[-_]?record)/i,
66
+ // log.* with PHI (Winston, Bunyan, etc.)
67
+ /log\.(?:error|warn|info|debug)\s*\([^)]*(?:patient|ssn|dob|mrn|diagnosis|medication|health[-_]?record)/i,
68
+ // console with patient data object
69
+ /console\.[a-z]+\s*\([^)]*patient(?:Data|Info|Record|Object)/i,
70
+ // logger with health record
71
+ /logger\.[a-z]+\s*\([^)]*health[-_]?record/i,
72
+ ],
73
+ negativePatterns: [
74
+ // Redacted or masked PHI
75
+ /redact/i,
76
+ /mask/i,
77
+ /sanitize/i,
78
+ /obfuscate/i,
79
+ // Generic messages without actual data
80
+ /['"]Patient not found['"]/i,
81
+ /['"]Invalid patient ID['"]/i,
82
+ /['"]Health record/i,
83
+ // Patient ID only (not full PHI)
84
+ /patient[-_]?id\b/i,
85
+ // Test files
86
+ /\.test\./i,
87
+ /\.spec\./i,
88
+ /describe\(/i,
89
+ ],
90
+ recommendation: 'Never log PHI in error messages. Redact sensitive data before logging. Example: logger.error("Error processing patient", { patientId: redact(patient.id) }). Use patient IDs only, never full PHI.',
91
+ category: 'phi-exposure',
92
+ };
93
+ export const ALL_ERROR_PATTERNS = [
94
+ UNSANITIZED_ERROR_RESPONSE,
95
+ PHI_IN_ERROR_LOGS,
96
+ ];
97
+ //# sourceMappingURL=patterns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../../src/scanners/errors/patterns.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAiB;IACtD,EAAE,EAAE,WAAW;IACf,IAAI,EAAE,wCAAwC;IAC9C,WAAW,EACT,sIAAsI;IACxI,QAAQ,EAAE,MAAM;IAChB,cAAc,EAAE,qCAAqC;IACrD,QAAQ,EAAE;QACR,iCAAiC;QACjC,gDAAgD;QAEhD,mCAAmC;QACnC,kDAAkD;QAElD,+DAA+D;QAC/D,4CAA4C;QAE5C,+BAA+B;QAC/B,qDAAqD;QAErD,8BAA8B;QAC9B,iEAAiE;QAEjE,iCAAiC;QACjC,8BAA8B;QAE9B,yBAAyB;QACzB,4BAA4B;KAC7B;IACD,gBAAgB,EAAE;QAChB,2BAA2B;QAC3B,WAAW;QACX,eAAe;QACf,cAAc;QAEd,iCAAiC;QACjC,uEAAuE;QAEvE,gCAAgC;QAChC,YAAY;QACZ,WAAW;QACX,QAAQ;QAER,iCAAiC;QACjC,sDAAsD;QACtD,gBAAgB;KACjB;IACD,cAAc,EACZ,4MAA4M;IAC9M,QAAQ,EAAE,eAAe;CAC1B,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAiB;IAC7C,EAAE,EAAE,WAAW;IACf,IAAI,EAAE,yCAAyC;IAC/C,WAAW,EACT,8IAA8I;IAChJ,QAAQ,EAAE,UAAU;IACpB,cAAc,EAAE,yCAAyC;IACzD,QAAQ,EAAE;QACR,qBAAqB;QACrB,iHAAiH;QAEjH,oBAAoB;QACpB,gHAAgH;QAEhH,uBAAuB;QACvB,mGAAmG;QAEnG,yCAAyC;QACzC,yGAAyG;QAEzG,mCAAmC;QACnC,8DAA8D;QAE9D,4BAA4B;QAC5B,4CAA4C;KAC7C;IACD,gBAAgB,EAAE;QAChB,yBAAyB;QACzB,SAAS;QACT,OAAO;QACP,WAAW;QACX,YAAY;QAEZ,uCAAuC;QACvC,4BAA4B;QAC5B,6BAA6B;QAC7B,oBAAoB;QAEpB,iCAAiC;QACjC,mBAAmB;QAEnB,aAAa;QACb,WAAW;QACX,WAAW;QACX,aAAa;KACd;IACD,cAAc,EACZ,oMAAoM;IACtM,QAAQ,EAAE,cAAc;CACzB,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAmB;IAChD,0BAA0B;IAC1B,iBAAiB;CAClB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * HIPAA 2026 Security Rule Scanner
3
+ * Implements detection for 15 technical requirements (all now "required")
4
+ * Expected enforcement: May 2026
5
+ */
6
+ import type { Scanner } from '../../types.js';
7
+ export declare const hipaa2026Scanner: Scanner;
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/scanners/hipaa2026/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAwB,MAAM,gBAAgB,CAAC;AAoRpE,eAAO,MAAM,gBAAgB,EAAE,OAyI9B,CAAC"}