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,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 @@
|
|
|
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":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAElC,OAAO,EACL,uBAAuB,GAExB,MAAM,eAAe,CAAC;AAEvB,MAAM,CAAC,MAAM,kBAAkB,GAAY;IACzC,IAAI,EAAE,6BAA6B;IACnC,QAAQ,EAAE,YAAY;IAEtB,KAAK,CAAC,IAAI,CAAC,KAAe,EAAE,OAAoB;QAC9C,MAAM,QAAQ,GAAc,EAAE,CAAC;QAE/B,kCAAkC;QAClC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACnC,4DAA4D,CAAC,IAAI,CAAC,CAAC,CAAC,CACrE,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBACjD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAElC,KAAK,MAAM,OAAO,IAAI,uBAAuB,EAAE,CAAC;oBAC9C,wDAAwD;oBACxD,IAAI,OAAO,CAAC,EAAE,KAAK,UAAU,EAAE,CAAC;wBAC9B,MAAM,uBAAuB,CAC3B,IAAI,EACJ,OAAO,EACP,KAAK,EACL,OAAO,EACP,QAAQ,CACT,CAAC;wBACF,SAAS;oBACX,CAAC;oBAED,sDAAsD;oBACtD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;wBACtB,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC;wBAEzB,gCAAgC;wBAChC,IAAI,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC;4BAAE,SAAS;wBAEpD,0CAA0C;wBAC1C,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;wBAC3D,IAAI,CAAC,OAAO;4BAAE,SAAS;wBAEvB,iDAAiD;wBACjD,MAAM,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;4BAClD,yCAAyC;4BACzC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;gCAAE,OAAO,IAAI,CAAC;4BAE9B,wDAAwD;4BACxD,IAAI,OAAO,CAAC,EAAE,KAAK,UAAU,EAAE,CAAC;gCAC9B,mCAAmC;gCACnC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;gCAC5D,IAAI,UAAU,EAAE,CAAC;oCACf,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;oCAC5B,0CAA0C;oCAC1C,IACE,uFAAuF,CAAC,IAAI,CAC1F,KAAK,CACN,EACD,CAAC;wCACD,OAAO,IAAI,CAAC;oCACd,CAAC;oCACD,yCAAyC;oCACzC,IACE,KAAK,CAAC,MAAM,GAAG,CAAC;wCAChB,wCAAwC,CAAC,IAAI,CAAC,KAAK,CAAC,EACpD,CAAC;wCACD,OAAO,IAAI,CAAC;oCACd,CAAC;gCACH,CAAC;4BACH,CAAC;4BAED,OAAO,KAAK,CAAC;wBACf,CAAC,CAAC,CAAC;wBAEH,IAAI,MAAM;4BAAE,SAAS;wBAErB,iBAAiB;wBACjB,QAAQ,CAAC,IAAI,CAAC;4BACZ,EAAE,EAAE,OAAO,CAAC,EAAE;4BACd,QAAQ,EAAE,YAAY;4BACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;4BAC1B,KAAK,EAAE,OAAO,CAAC,IAAI;4BACnB,WAAW,EAAE,GAAG,OAAO,CAAC,WAAW,aAAa,IAAI,CAAC,IAAI,EAAE,EAAE;4BAC7D,IAAI,EAAE,IAAI;4BACV,IAAI,EAAE,UAAU;4BAChB,cAAc,EAAE,OAAO,CAAC,cAAc;4BACtC,cAAc,EAAE,OAAO,CAAC,cAAc;4BACtC,UAAU,EAAE,MAAM;yBACnB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,gCAAgC;YAClC,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEF;;GAEG;AACH,KAAK,UAAU,uBAAuB,CACpC,IAAY,EACZ,OAAe,EACf,KAAe,EACf,OAA0B,EAC1B,QAAmB;IAEnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC;QAEzB,gBAAgB;QAChB,IAAI,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QAElD,sCAAsC;QACtC,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,WAAW;YAAE,SAAS;QAE3B,iFAAiF;QACjF,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACxC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEjE,+CAA+C;QAC/C,MAAM,iBAAiB,GACrB,sCAAsC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEvD,yEAAyE;QACzE,MAAM,aAAa,GAAG,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACzD,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAChB,CAAC;QAEF,IAAI,aAAa;YAAE,SAAS;QAE5B,+DAA+D;QAC/D,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,EAAE,IAAI,CACrD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CACjE,CAAC;QAEF,IAAI,gBAAgB;YAAE,SAAS;QAE/B,4CAA4C;QAC5C,IAAI,iBAAiB,EAAE,CAAC;YACtB,QAAQ,CAAC,IAAI,CAAC;gBACZ,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,QAAQ,EAAE,YAAY;gBACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,KAAK,EAAE,OAAO,CAAC,IAAI;gBACnB,WAAW,EAAE,GAAG,OAAO,CAAC,WAAW,aAAa,IAAI,CAAC,IAAI,EAAE,+DAA+D;gBAC1H,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,UAAU;gBAChB,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,UAAU,EAAE,MAAM;aACnB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../src/scanners/credentials/index.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|