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.
- package/README.md +251 -615
- package/dist/cli.js +542 -0
- package/dist/cli.js.map +1 -1
- package/dist/marketplace/index.d.ts +8 -0
- package/dist/marketplace/index.d.ts.map +1 -0
- package/dist/marketplace/index.js +7 -0
- package/dist/marketplace/index.js.map +1 -0
- package/dist/marketplace/installer.d.ts +62 -0
- package/dist/marketplace/installer.d.ts.map +1 -0
- package/dist/marketplace/installer.js +254 -0
- package/dist/marketplace/installer.js.map +1 -0
- package/dist/marketplace/registry.d.ts +52 -0
- package/dist/marketplace/registry.d.ts.map +1 -0
- package/dist/marketplace/registry.js +759 -0
- package/dist/marketplace/registry.js.map +1 -0
- package/dist/marketplace/types.d.ts +123 -0
- package/dist/marketplace/types.d.ts.map +1 -0
- package/dist/marketplace/types.js +6 -0
- package/dist/marketplace/types.js.map +1 -0
- package/dist/reporters/audit-report.d.ts.map +1 -1
- package/dist/reporters/audit-report.js +180 -0
- package/dist/reporters/audit-report.js.map +1 -1
- package/dist/reporters/index.d.ts.map +1 -1
- package/dist/reporters/index.js +2612 -5
- package/dist/reporters/index.js.map +1 -1
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +15 -1
- package/dist/scan.js.map +1 -1
- package/dist/scanners/api-security/index.d.ts +7 -0
- package/dist/scanners/api-security/index.d.ts.map +1 -0
- package/dist/scanners/api-security/index.js +139 -0
- package/dist/scanners/api-security/index.js.map +1 -0
- package/dist/scanners/api-security/index.test.d.ts +5 -0
- package/dist/scanners/api-security/index.test.d.ts.map +1 -0
- package/dist/scanners/api-security/index.test.js +360 -0
- package/dist/scanners/api-security/index.test.js.map +1 -0
- package/dist/scanners/api-security/patterns.d.ts +32 -0
- package/dist/scanners/api-security/patterns.d.ts.map +1 -0
- package/dist/scanners/api-security/patterns.js +159 -0
- package/dist/scanners/api-security/patterns.js.map +1 -0
- package/dist/scanners/authentication/index.d.ts +7 -0
- package/dist/scanners/authentication/index.d.ts.map +1 -0
- package/dist/scanners/authentication/index.js +107 -0
- package/dist/scanners/authentication/index.js.map +1 -0
- package/dist/scanners/authentication/index.test.d.ts +5 -0
- package/dist/scanners/authentication/index.test.d.ts.map +1 -0
- package/dist/scanners/authentication/index.test.js +379 -0
- package/dist/scanners/authentication/index.test.js.map +1 -0
- package/dist/scanners/authentication/patterns.d.ts +32 -0
- package/dist/scanners/authentication/patterns.d.ts.map +1 -0
- package/dist/scanners/authentication/patterns.js +133 -0
- package/dist/scanners/authentication/patterns.js.map +1 -0
- package/dist/scanners/configuration/index.d.ts +8 -0
- package/dist/scanners/configuration/index.d.ts.map +1 -0
- package/dist/scanners/configuration/index.js +87 -0
- package/dist/scanners/configuration/index.js.map +1 -0
- package/dist/scanners/configuration/index.test.d.ts +5 -0
- package/dist/scanners/configuration/index.test.d.ts.map +1 -0
- package/dist/scanners/configuration/index.test.js +344 -0
- package/dist/scanners/configuration/index.test.js.map +1 -0
- package/dist/scanners/configuration/patterns.d.ts +32 -0
- package/dist/scanners/configuration/patterns.d.ts.map +1 -0
- package/dist/scanners/configuration/patterns.js +146 -0
- package/dist/scanners/configuration/patterns.js.map +1 -0
- package/dist/scanners/credentials/index.d.ts +7 -0
- package/dist/scanners/credentials/index.d.ts.map +1 -0
- package/dist/scanners/credentials/index.js +129 -0
- package/dist/scanners/credentials/index.js.map +1 -0
- package/dist/scanners/credentials/index.test.d.ts +5 -0
- package/dist/scanners/credentials/index.test.d.ts.map +1 -0
- package/dist/scanners/credentials/index.test.js +395 -0
- package/dist/scanners/credentials/index.test.js.map +1 -0
- package/dist/scanners/credentials/patterns.d.ts +32 -0
- package/dist/scanners/credentials/patterns.d.ts.map +1 -0
- package/dist/scanners/credentials/patterns.js +140 -0
- package/dist/scanners/credentials/patterns.js.map +1 -0
- package/dist/scanners/errors/index.d.ts +8 -0
- package/dist/scanners/errors/index.d.ts.map +1 -0
- package/dist/scanners/errors/index.js +78 -0
- package/dist/scanners/errors/index.js.map +1 -0
- package/dist/scanners/errors/index.test.d.ts +5 -0
- package/dist/scanners/errors/index.test.d.ts.map +1 -0
- package/dist/scanners/errors/index.test.js +330 -0
- package/dist/scanners/errors/index.test.js.map +1 -0
- package/dist/scanners/errors/patterns.d.ts +27 -0
- package/dist/scanners/errors/patterns.d.ts.map +1 -0
- package/dist/scanners/errors/patterns.js +97 -0
- package/dist/scanners/errors/patterns.js.map +1 -0
- package/dist/scanners/hipaa2026/index.d.ts +8 -0
- package/dist/scanners/hipaa2026/index.d.ts.map +1 -0
- package/dist/scanners/hipaa2026/index.js +345 -0
- package/dist/scanners/hipaa2026/index.js.map +1 -0
- package/dist/scanners/hipaa2026/index.test.d.ts +5 -0
- package/dist/scanners/hipaa2026/index.test.d.ts.map +1 -0
- package/dist/scanners/hipaa2026/index.test.js +332 -0
- package/dist/scanners/hipaa2026/index.test.js.map +1 -0
- package/dist/scanners/hipaa2026/patterns.d.ts +57 -0
- package/dist/scanners/hipaa2026/patterns.d.ts.map +1 -0
- package/dist/scanners/hipaa2026/patterns.js +268 -0
- package/dist/scanners/hipaa2026/patterns.js.map +1 -0
- package/dist/scanners/operational/index.d.ts +7 -0
- package/dist/scanners/operational/index.d.ts.map +1 -0
- package/dist/scanners/operational/index.js +171 -0
- package/dist/scanners/operational/index.js.map +1 -0
- package/dist/scanners/operational/index.test.d.ts +5 -0
- package/dist/scanners/operational/index.test.d.ts.map +1 -0
- package/dist/scanners/operational/index.test.js +406 -0
- package/dist/scanners/operational/index.test.js.map +1 -0
- package/dist/scanners/operational/patterns.d.ts +33 -0
- package/dist/scanners/operational/patterns.d.ts.map +1 -0
- package/dist/scanners/operational/patterns.js +151 -0
- package/dist/scanners/operational/patterns.js.map +1 -0
- package/dist/scanners/rbac/index.d.ts +7 -0
- package/dist/scanners/rbac/index.d.ts.map +1 -0
- package/dist/scanners/rbac/index.js +145 -0
- package/dist/scanners/rbac/index.js.map +1 -0
- package/dist/scanners/rbac/index.test.d.ts +5 -0
- package/dist/scanners/rbac/index.test.d.ts.map +1 -0
- package/dist/scanners/rbac/index.test.js +422 -0
- package/dist/scanners/rbac/index.test.js.map +1 -0
- package/dist/scanners/rbac/patterns.d.ts +32 -0
- package/dist/scanners/rbac/patterns.d.ts.map +1 -0
- package/dist/scanners/rbac/patterns.js +124 -0
- package/dist/scanners/rbac/patterns.js.map +1 -0
- package/dist/scanners/revocation/index.d.ts +8 -0
- package/dist/scanners/revocation/index.d.ts.map +1 -0
- package/dist/scanners/revocation/index.js +83 -0
- package/dist/scanners/revocation/index.js.map +1 -0
- package/dist/scanners/revocation/index.test.d.ts +5 -0
- package/dist/scanners/revocation/index.test.d.ts.map +1 -0
- package/dist/scanners/revocation/index.test.js +332 -0
- package/dist/scanners/revocation/index.test.js.map +1 -0
- package/dist/scanners/revocation/patterns.d.ts +27 -0
- package/dist/scanners/revocation/patterns.d.ts.map +1 -0
- package/dist/scanners/revocation/patterns.js +109 -0
- package/dist/scanners/revocation/patterns.js.map +1 -0
- package/dist/scanners/sanitization/index.d.ts +8 -0
- package/dist/scanners/sanitization/index.d.ts.map +1 -0
- package/dist/scanners/sanitization/index.js +98 -0
- package/dist/scanners/sanitization/index.js.map +1 -0
- package/dist/scanners/sanitization/index.test.d.ts +5 -0
- package/dist/scanners/sanitization/index.test.d.ts.map +1 -0
- package/dist/scanners/sanitization/index.test.js +370 -0
- package/dist/scanners/sanitization/index.test.js.map +1 -0
- package/dist/scanners/sanitization/patterns.d.ts +27 -0
- package/dist/scanners/sanitization/patterns.d.ts.map +1 -0
- package/dist/scanners/sanitization/patterns.js +117 -0
- package/dist/scanners/sanitization/patterns.js.map +1 -0
- package/dist/training/certificate.d.ts +26 -0
- package/dist/training/certificate.d.ts.map +1 -0
- package/dist/training/certificate.js +92 -0
- package/dist/training/certificate.js.map +1 -0
- package/dist/training/index.d.ts +3 -0
- package/dist/training/index.d.ts.map +1 -0
- package/dist/training/index.js +243 -0
- package/dist/training/index.js.map +1 -0
- package/dist/training/modules.d.ts +13 -0
- package/dist/training/modules.d.ts.map +1 -0
- package/dist/training/modules.js +608 -0
- package/dist/training/modules.js.map +1 -0
- package/dist/training/questions.d.ts +9 -0
- package/dist/training/questions.d.ts.map +1 -0
- package/dist/training/questions.js +505 -0
- package/dist/training/questions.js.map +1 -0
- package/dist/types.d.ts +45 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/npm-audit.d.ts +6 -0
- package/dist/utils/npm-audit.d.ts.map +1 -0
- package/dist/utils/npm-audit.js +95 -0
- package/dist/utils/npm-audit.js.map +1 -0
- package/dist/utils/scan-history.d.ts +59 -0
- package/dist/utils/scan-history.d.ts.map +1 -0
- package/dist/utils/scan-history.js +170 -0
- package/dist/utils/scan-history.js.map +1 -0
- package/package.json +4 -1
- package/templates/baa-verification-letter.md +105 -0
- package/templates/irp.md +545 -0
- package/templates/notice-of-privacy-practices.md +491 -0
- package/templates/physical-safeguards-checklist.md +247 -0
- package/templates/security-officer-designation.md +237 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for HIPAA 2026 Security Rule Scanner
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
5
|
+
import { hipaa2026Scanner } from './index.js';
|
|
6
|
+
import * as fs from 'fs/promises';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import * as os from 'os';
|
|
9
|
+
describe('HIPAA 2026 Scanner', () => {
|
|
10
|
+
let tempDir = '';
|
|
11
|
+
let testFiles = [];
|
|
12
|
+
beforeEach(async () => {
|
|
13
|
+
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'hipaa2026-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('HIPAA-MFA-001: Multi-Factor Authentication', () => {
|
|
43
|
+
it('should detect PHI access without MFA', async () => {
|
|
44
|
+
const file = await createTestFile('auth.ts', `
|
|
45
|
+
app.post('/login', async (req, res) => {
|
|
46
|
+
const user = await authenticateUser(req.body);
|
|
47
|
+
if (user.role === 'doctor') {
|
|
48
|
+
accessPatientRecords(user);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
`);
|
|
52
|
+
const findings = await hipaa2026Scanner.scan([file], scanOptions);
|
|
53
|
+
const mfaFindings = findings.filter((f) => f.id === 'HIPAA-MFA-001');
|
|
54
|
+
expect(mfaFindings.length).toBeGreaterThan(0);
|
|
55
|
+
expect(mfaFindings[0].severity).toBe('critical');
|
|
56
|
+
expect(mfaFindings[0].hipaaReference).toContain('164.312(a)(2)(i)');
|
|
57
|
+
});
|
|
58
|
+
it('should not flag PHI access with MFA', async () => {
|
|
59
|
+
const file = await createTestFile('auth-secure.ts', `
|
|
60
|
+
app.post('/login', async (req, res) => {
|
|
61
|
+
const user = await authenticateUser(req.body);
|
|
62
|
+
if (!user.mfaVerified) {
|
|
63
|
+
return res.status(401).json({ error: 'MFA required' });
|
|
64
|
+
}
|
|
65
|
+
if (user.role === 'doctor') {
|
|
66
|
+
accessPatientRecords(user);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
`);
|
|
70
|
+
const findings = await hipaa2026Scanner.scan([file], scanOptions);
|
|
71
|
+
const mfaFindings = findings.filter((f) => f.id === 'HIPAA-MFA-001');
|
|
72
|
+
expect(mfaFindings.length).toBe(0);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
describe('HIPAA-ENC-REST-001: Encryption at Rest', () => {
|
|
76
|
+
it('should detect database without encryption', async () => {
|
|
77
|
+
const file = await createTestFile('db.ts', `
|
|
78
|
+
import mongoose from 'mongoose';
|
|
79
|
+
|
|
80
|
+
mongoose.connect('mongodb://localhost:27017/patients', {
|
|
81
|
+
useNewUrlParser: true,
|
|
82
|
+
});
|
|
83
|
+
`);
|
|
84
|
+
const findings = await hipaa2026Scanner.scan([file], scanOptions);
|
|
85
|
+
const encFindings = findings.filter((f) => f.id === 'HIPAA-ENC-REST-001');
|
|
86
|
+
expect(encFindings.length).toBeGreaterThan(0);
|
|
87
|
+
expect(encFindings[0].severity).toBe('critical');
|
|
88
|
+
});
|
|
89
|
+
it('should not flag database with encryption', async () => {
|
|
90
|
+
const file = await createTestFile('db-secure.ts', `
|
|
91
|
+
import mongoose from 'mongoose';
|
|
92
|
+
|
|
93
|
+
mongoose.connect('mongodb://localhost:27017/patients', {
|
|
94
|
+
useNewUrlParser: true,
|
|
95
|
+
ssl: true,
|
|
96
|
+
encrypt: true,
|
|
97
|
+
});
|
|
98
|
+
`);
|
|
99
|
+
const findings = await hipaa2026Scanner.scan([file], scanOptions);
|
|
100
|
+
const encFindings = findings.filter((f) => f.id === 'HIPAA-ENC-REST-001');
|
|
101
|
+
expect(encFindings.length).toBe(0);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
describe('HIPAA-SESSION-001: Session Timeout', () => {
|
|
105
|
+
it('should detect session without timeout', async () => {
|
|
106
|
+
const file = await createTestFile('session.ts', `
|
|
107
|
+
import session from 'express-session';
|
|
108
|
+
|
|
109
|
+
app.use(session({
|
|
110
|
+
secret: 'my-secret',
|
|
111
|
+
resave: false,
|
|
112
|
+
saveUninitialized: false,
|
|
113
|
+
}));
|
|
114
|
+
`);
|
|
115
|
+
const findings = await hipaa2026Scanner.scan([file], scanOptions);
|
|
116
|
+
const sessionFindings = findings.filter((f) => f.id === 'HIPAA-SESSION-001');
|
|
117
|
+
expect(sessionFindings.length).toBeGreaterThan(0);
|
|
118
|
+
expect(sessionFindings[0].severity).toBe('high');
|
|
119
|
+
});
|
|
120
|
+
it('should not flag session with proper timeout', async () => {
|
|
121
|
+
const file = await createTestFile('session-secure.ts', `
|
|
122
|
+
import session from 'express-session';
|
|
123
|
+
|
|
124
|
+
app.use(session({
|
|
125
|
+
secret: 'my-secret',
|
|
126
|
+
resave: false,
|
|
127
|
+
saveUninitialized: false,
|
|
128
|
+
cookie: { maxAge: 900000 } // 15 minutes
|
|
129
|
+
}));
|
|
130
|
+
`);
|
|
131
|
+
const findings = await hipaa2026Scanner.scan([file], scanOptions);
|
|
132
|
+
const sessionFindings = findings.filter((f) => f.id === 'HIPAA-SESSION-001');
|
|
133
|
+
expect(sessionFindings.length).toBe(0);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
describe('HIPAA-REVOKE-001: Access Revocation', () => {
|
|
137
|
+
it('should detect user deactivation without token revocation', async () => {
|
|
138
|
+
const file = await createTestFile('user.ts', `
|
|
139
|
+
async function deactivateUser(userId: string) {
|
|
140
|
+
await User.update({ id: userId }, { active: false });
|
|
141
|
+
console.log('User deactivated');
|
|
142
|
+
}
|
|
143
|
+
`);
|
|
144
|
+
const findings = await hipaa2026Scanner.scan([file], scanOptions);
|
|
145
|
+
const revokeFindings = findings.filter((f) => f.id === 'HIPAA-REVOKE-001');
|
|
146
|
+
expect(revokeFindings.length).toBeGreaterThan(0);
|
|
147
|
+
expect(revokeFindings[0].severity).toBe('critical');
|
|
148
|
+
});
|
|
149
|
+
it('should not flag deactivation with token revocation', async () => {
|
|
150
|
+
const file = await createTestFile('user-secure.ts', `
|
|
151
|
+
async function deactivateUser(userId: string) {
|
|
152
|
+
await User.update({ id: userId }, { active: false });
|
|
153
|
+
await revokeAllTokens(userId);
|
|
154
|
+
await invalidateAllSessions(userId);
|
|
155
|
+
console.log('User deactivated and tokens revoked');
|
|
156
|
+
}
|
|
157
|
+
`);
|
|
158
|
+
const findings = await hipaa2026Scanner.scan([file], scanOptions);
|
|
159
|
+
const revokeFindings = findings.filter((f) => f.id === 'HIPAA-REVOKE-001');
|
|
160
|
+
expect(revokeFindings.length).toBe(0);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
describe('HIPAA-BREACH-001: Breach Notification', () => {
|
|
164
|
+
it('should detect security errors without breach notification', async () => {
|
|
165
|
+
const file = await createTestFile('api.ts', `
|
|
166
|
+
try {
|
|
167
|
+
await processPhiData(data);
|
|
168
|
+
} catch (error) {
|
|
169
|
+
if (error.message.includes('unauthorized')) {
|
|
170
|
+
console.error('Security breach detected');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
`);
|
|
174
|
+
const findings = await hipaa2026Scanner.scan([file], scanOptions);
|
|
175
|
+
const breachFindings = findings.filter((f) => f.id === 'HIPAA-BREACH-001');
|
|
176
|
+
expect(breachFindings.length).toBeGreaterThan(0);
|
|
177
|
+
expect(breachFindings[0].severity).toBe('critical');
|
|
178
|
+
});
|
|
179
|
+
it('should not flag errors with breach notification', async () => {
|
|
180
|
+
const file = await createTestFile('api-secure.ts', `
|
|
181
|
+
try {
|
|
182
|
+
await processPhiData(data);
|
|
183
|
+
} catch (error) {
|
|
184
|
+
if (error.message.includes('unauthorized')) {
|
|
185
|
+
console.error('Security breach detected');
|
|
186
|
+
await notifyBreach(error);
|
|
187
|
+
await incidentResponse.trigger('security-breach');
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
`);
|
|
191
|
+
const findings = await hipaa2026Scanner.scan([file], scanOptions);
|
|
192
|
+
const breachFindings = findings.filter((f) => f.id === 'HIPAA-BREACH-001');
|
|
193
|
+
expect(breachFindings.length).toBe(0);
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
describe('HIPAA-SEGMENT-001: Network Segmentation', () => {
|
|
197
|
+
it('should detect CORS wildcard for PHI endpoints', async () => {
|
|
198
|
+
const file = await createTestFile('cors.ts', `
|
|
199
|
+
import cors from 'cors';
|
|
200
|
+
|
|
201
|
+
app.use(cors({ origin: '*' }));
|
|
202
|
+
|
|
203
|
+
app.get('/api/patients', async (req, res) => {
|
|
204
|
+
const patients = await getPatients();
|
|
205
|
+
res.json(patients);
|
|
206
|
+
});
|
|
207
|
+
`);
|
|
208
|
+
const findings = await hipaa2026Scanner.scan([file], scanOptions);
|
|
209
|
+
const segmentFindings = findings.filter((f) => f.id === 'HIPAA-SEGMENT-001');
|
|
210
|
+
expect(segmentFindings.length).toBeGreaterThan(0);
|
|
211
|
+
expect(segmentFindings[0].severity).toBe('critical');
|
|
212
|
+
});
|
|
213
|
+
it('should not flag CORS with origin whitelist', async () => {
|
|
214
|
+
const file = await createTestFile('cors-secure.ts', `
|
|
215
|
+
import cors from 'cors';
|
|
216
|
+
|
|
217
|
+
app.use(cors({ origin: ['https://hospital.com', 'https://ehr.hospital.com'] }));
|
|
218
|
+
|
|
219
|
+
app.get('/api/patients', async (req, res) => {
|
|
220
|
+
const patients = await getPatients();
|
|
221
|
+
res.json(patients);
|
|
222
|
+
});
|
|
223
|
+
`);
|
|
224
|
+
const findings = await hipaa2026Scanner.scan([file], scanOptions);
|
|
225
|
+
const segmentFindings = findings.filter((f) => f.id === 'HIPAA-SEGMENT-001');
|
|
226
|
+
expect(segmentFindings.length).toBe(0);
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
describe('HIPAA-ASSET-001: Technology Asset Inventory', () => {
|
|
230
|
+
it('should generate asset inventory', async () => {
|
|
231
|
+
await createTestFile('services.ts', `
|
|
232
|
+
import mongoose from 'mongoose';
|
|
233
|
+
import { S3Client } from '@aws-sdk/client-s3';
|
|
234
|
+
import axios from 'axios';
|
|
235
|
+
|
|
236
|
+
mongoose.connect('mongodb://localhost/patients');
|
|
237
|
+
const s3 = new S3Client({ region: 'us-east-1' });
|
|
238
|
+
axios.get('https://api.external.com/patient-data');
|
|
239
|
+
`);
|
|
240
|
+
const findings = await hipaa2026Scanner.scan(testFiles, scanOptions);
|
|
241
|
+
const assetFindings = findings.filter((f) => f.id === 'HIPAA-ASSET-001');
|
|
242
|
+
expect(assetFindings.length).toBe(1);
|
|
243
|
+
expect(assetFindings[0].severity).toBe('high');
|
|
244
|
+
expect(assetFindings[0].file).toBe('ASSET-INVENTORY');
|
|
245
|
+
expect(assetFindings[0].recommendation).toContain('DATABASE');
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
describe('HIPAA-FLOW-001: PHI Flow Mapping', () => {
|
|
249
|
+
it('should generate PHI flow map', async () => {
|
|
250
|
+
await createTestFile('patient-flow.ts', `
|
|
251
|
+
app.post('/api/patient', async (req, res) => {
|
|
252
|
+
const patientData = req.body.patient;
|
|
253
|
+
const validated = validatePatient(patientData);
|
|
254
|
+
await savePatient(validated);
|
|
255
|
+
return res.json({ success: true, patient: validated });
|
|
256
|
+
});
|
|
257
|
+
`);
|
|
258
|
+
const findings = await hipaa2026Scanner.scan(testFiles, scanOptions);
|
|
259
|
+
const flowFindings = findings.filter((f) => f.id === 'HIPAA-FLOW-001');
|
|
260
|
+
expect(flowFindings.length).toBe(1);
|
|
261
|
+
expect(flowFindings[0].severity).toBe('high');
|
|
262
|
+
expect(flowFindings[0].file).toBe('PHI-FLOW-MAP');
|
|
263
|
+
expect(flowFindings[0].recommendation).toContain('INPUT');
|
|
264
|
+
expect(flowFindings[0].recommendation).toContain('PROCESSING');
|
|
265
|
+
expect(flowFindings[0].recommendation).toContain('STORAGE');
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
describe('HIPAA-PENTEST-001: Vulnerability Scanning', () => {
|
|
269
|
+
it('should detect missing vulnerability scanning config exactly once', async () => {
|
|
270
|
+
// Create multiple code files to verify it only reports once
|
|
271
|
+
await createTestFile('app.ts', 'const x = 1;');
|
|
272
|
+
await createTestFile('server.ts', 'const y = 2;');
|
|
273
|
+
await createTestFile('index.ts', 'const z = 3;');
|
|
274
|
+
const findings = await hipaa2026Scanner.scan(testFiles, { path: tempDir });
|
|
275
|
+
const pentestFindings = findings.filter((f) => f.id === 'HIPAA-PENTEST-001');
|
|
276
|
+
expect(pentestFindings.length).toBe(1);
|
|
277
|
+
expect(pentestFindings[0].severity).toBe('high');
|
|
278
|
+
expect(pentestFindings[0].file).toBe('project-level');
|
|
279
|
+
});
|
|
280
|
+
it('should not flag when dependabot exists', async () => {
|
|
281
|
+
const githubDir = path.join(tempDir, '.github');
|
|
282
|
+
await fs.mkdir(githubDir, { recursive: true });
|
|
283
|
+
await fs.writeFile(path.join(githubDir, 'dependabot.yml'), 'version: 2\nupdates:\n - package-ecosystem: npm', 'utf-8');
|
|
284
|
+
await createTestFile('app.ts', 'const x = 1;');
|
|
285
|
+
const findings = await hipaa2026Scanner.scan(testFiles, { path: tempDir });
|
|
286
|
+
const pentestFindings = findings.filter((f) => f.id === 'HIPAA-PENTEST-001');
|
|
287
|
+
expect(pentestFindings.length).toBe(0);
|
|
288
|
+
});
|
|
289
|
+
it('should not flag when semgrep config exists', async () => {
|
|
290
|
+
await fs.writeFile(path.join(tempDir, '.semgrep.yml'), 'rules: []', 'utf-8');
|
|
291
|
+
await createTestFile('app.ts', 'const x = 1;');
|
|
292
|
+
const findings = await hipaa2026Scanner.scan(testFiles, { path: tempDir });
|
|
293
|
+
const pentestFindings = findings.filter((f) => f.id === 'HIPAA-PENTEST-001');
|
|
294
|
+
expect(pentestFindings.length).toBe(0);
|
|
295
|
+
});
|
|
296
|
+
it('should not flag when workflow contains security scanning', async () => {
|
|
297
|
+
const workflowDir = path.join(tempDir, '.github', 'workflows');
|
|
298
|
+
await fs.mkdir(workflowDir, { recursive: true });
|
|
299
|
+
await fs.writeFile(path.join(workflowDir, 'ci.yml'), 'name: CI\njobs:\n scan:\n steps:\n - run: npm audit', 'utf-8');
|
|
300
|
+
await createTestFile('app.ts', 'const x = 1;');
|
|
301
|
+
const findings = await hipaa2026Scanner.scan(testFiles, { path: tempDir });
|
|
302
|
+
const pentestFindings = findings.filter((f) => f.id === 'HIPAA-PENTEST-001');
|
|
303
|
+
expect(pentestFindings.length).toBe(0);
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
describe('General Scanner Behavior', () => {
|
|
307
|
+
it('should only scan code files', async () => {
|
|
308
|
+
await createTestFile('README.md', 'patient data here');
|
|
309
|
+
await createTestFile('data.json', '{"patient": "data"}');
|
|
310
|
+
await createTestFile('code.ts', 'const patient = req.body;');
|
|
311
|
+
const findings = await hipaa2026Scanner.scan(testFiles, scanOptions);
|
|
312
|
+
// Should only find findings in code.ts
|
|
313
|
+
const uniqueFiles = new Set(findings.map((f) => path.basename(f.file)));
|
|
314
|
+
expect(uniqueFiles.has('README.md')).toBe(false);
|
|
315
|
+
expect(uniqueFiles.has('data.json')).toBe(false);
|
|
316
|
+
});
|
|
317
|
+
it('should include confidence scores', async () => {
|
|
318
|
+
const file = await createTestFile('auth.ts', `
|
|
319
|
+
app.post('/login', async (req) => {
|
|
320
|
+
const user = await authenticateUser(req.body);
|
|
321
|
+
accessPatientRecords(user);
|
|
322
|
+
});
|
|
323
|
+
`);
|
|
324
|
+
const findings = await hipaa2026Scanner.scan([file], scanOptions);
|
|
325
|
+
for (const finding of findings) {
|
|
326
|
+
expect(finding.confidence).toBeDefined();
|
|
327
|
+
expect(['high', 'medium', 'low']).toContain(finding.confidence);
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../src/scanners/hipaa2026/index.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HIPAA 2026 Security Rule Detection Patterns
|
|
3
|
+
* Covers 15 technical requirements (all now "required" instead of "addressable")
|
|
4
|
+
* Expected enforcement: May 2026
|
|
5
|
+
*/
|
|
6
|
+
export interface HIPAA2026Pattern {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
severity: 'critical' | 'high';
|
|
11
|
+
hipaaReference: string;
|
|
12
|
+
patterns: RegExp[];
|
|
13
|
+
negativePatterns?: RegExp[];
|
|
14
|
+
autoFix?: string;
|
|
15
|
+
confidence: 'high' | 'medium' | 'low';
|
|
16
|
+
category: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* HIPAA-MFA-001: Multi-Factor Authentication Enforcement
|
|
20
|
+
*/
|
|
21
|
+
export declare const MFA_PATTERNS: HIPAA2026Pattern;
|
|
22
|
+
/**
|
|
23
|
+
* HIPAA-ENC-REST-001: Encryption at Rest
|
|
24
|
+
*/
|
|
25
|
+
export declare const ENCRYPTION_AT_REST_PATTERNS: HIPAA2026Pattern;
|
|
26
|
+
/**
|
|
27
|
+
* HIPAA-SESSION-001: Automatic Session Timeout
|
|
28
|
+
*/
|
|
29
|
+
export declare const SESSION_TIMEOUT_PATTERNS: HIPAA2026Pattern;
|
|
30
|
+
/**
|
|
31
|
+
* HIPAA-REVOKE-001: Immediate Access Revocation
|
|
32
|
+
*/
|
|
33
|
+
export declare const ACCESS_REVOCATION_PATTERNS: HIPAA2026Pattern;
|
|
34
|
+
/**
|
|
35
|
+
* HIPAA-BREACH-001: 24-Hour Breach Notification
|
|
36
|
+
*/
|
|
37
|
+
export declare const BREACH_NOTIFICATION_PATTERNS: HIPAA2026Pattern;
|
|
38
|
+
/**
|
|
39
|
+
* HIPAA-SEGMENT-001: Network Segmentation
|
|
40
|
+
*/
|
|
41
|
+
export declare const NETWORK_SEGMENTATION_PATTERNS: HIPAA2026Pattern;
|
|
42
|
+
/**
|
|
43
|
+
* HIPAA-ASSET-001: Technology Asset Inventory
|
|
44
|
+
* Special pattern - triggers asset inventory generation
|
|
45
|
+
*/
|
|
46
|
+
export declare const ASSET_INVENTORY_PATTERNS: HIPAA2026Pattern;
|
|
47
|
+
/**
|
|
48
|
+
* HIPAA-FLOW-001: ePHI Flow Mapping
|
|
49
|
+
* Special pattern - triggers flow map generation
|
|
50
|
+
*/
|
|
51
|
+
export declare const PHI_FLOW_MAPPING_PATTERNS: HIPAA2026Pattern;
|
|
52
|
+
/**
|
|
53
|
+
* HIPAA-PENTEST-001: Vulnerability Scanning Configuration
|
|
54
|
+
*/
|
|
55
|
+
export declare const VULNERABILITY_SCANNING_PATTERNS: HIPAA2026Pattern;
|
|
56
|
+
export declare const ALL_HIPAA_2026_PATTERNS: HIPAA2026Pattern[];
|
|
57
|
+
//# sourceMappingURL=patterns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../../src/scanners/hipaa2026/patterns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,UAAU,GAAG,MAAM,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,gBA2B1B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,2BAA2B,EAAE,gBA6BzC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAE,gBA0BtC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,0BAA0B,EAAE,gBAyBxC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,4BAA4B,EAAE,gBAuB1C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,6BAA6B,EAAE,gBAyB3C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,gBAmBtC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,gBAmBvC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,+BAA+B,EAAE,gBAoB7C,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,gBAAgB,EAUrD,CAAC"}
|