devarmor 1.0.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 (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +35 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +140 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/index.d.ts +3 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +13 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/modules/agent-residue.d.ts +11 -0
  12. package/dist/modules/agent-residue.d.ts.map +1 -0
  13. package/dist/modules/agent-residue.js +283 -0
  14. package/dist/modules/agent-residue.js.map +1 -0
  15. package/dist/modules/mcp-auditor.d.ts +12 -0
  16. package/dist/modules/mcp-auditor.d.ts.map +1 -0
  17. package/dist/modules/mcp-auditor.js +290 -0
  18. package/dist/modules/mcp-auditor.js.map +1 -0
  19. package/dist/modules/posture-checker.d.ts +11 -0
  20. package/dist/modules/posture-checker.d.ts.map +1 -0
  21. package/dist/modules/posture-checker.js +315 -0
  22. package/dist/modules/posture-checker.js.map +1 -0
  23. package/dist/modules/secret-scanner.d.ts +11 -0
  24. package/dist/modules/secret-scanner.d.ts.map +1 -0
  25. package/dist/modules/secret-scanner.js +321 -0
  26. package/dist/modules/secret-scanner.js.map +1 -0
  27. package/dist/modules/skill-scanner.d.ts +12 -0
  28. package/dist/modules/skill-scanner.d.ts.map +1 -0
  29. package/dist/modules/skill-scanner.js +294 -0
  30. package/dist/modules/skill-scanner.js.map +1 -0
  31. package/dist/report/html.d.ts +6 -0
  32. package/dist/report/html.d.ts.map +1 -0
  33. package/dist/report/html.js +116 -0
  34. package/dist/report/html.js.map +1 -0
  35. package/dist/report/json.d.ts +9 -0
  36. package/dist/report/json.d.ts.map +1 -0
  37. package/dist/report/json.js +69 -0
  38. package/dist/report/json.js.map +1 -0
  39. package/dist/report/terminal.d.ts +6 -0
  40. package/dist/report/terminal.d.ts.map +1 -0
  41. package/dist/report/terminal.js +162 -0
  42. package/dist/report/terminal.js.map +1 -0
  43. package/dist/scanner.d.ts +9 -0
  44. package/dist/scanner.d.ts.map +1 -0
  45. package/dist/scanner.js +145 -0
  46. package/dist/scanner.js.map +1 -0
  47. package/dist/types.d.ts +91 -0
  48. package/dist/types.d.ts.map +1 -0
  49. package/dist/types.js +17 -0
  50. package/dist/types.js.map +1 -0
  51. package/package.json +50 -0
@@ -0,0 +1,290 @@
1
+ "use strict";
2
+ // ============================================================
3
+ // DevArmor — MCP Auditor Module
4
+ // Audits MCP server configurations for security issues.
5
+ // ============================================================
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.MCPAuditor = void 0;
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const os = __importStar(require("os"));
44
+ const types_1 = require("../types");
45
+ /** MCP config files to look for. */
46
+ const MCP_CONFIG_FILENAMES = [
47
+ 'claude_desktop_config.json',
48
+ '.mcp.json',
49
+ 'mcp.json',
50
+ ];
51
+ /** Dangerous command patterns that indicate shell injection risk. */
52
+ const DANGEROUS_COMMANDS = [
53
+ { pattern: /\brm\s+-rf\b/gi, label: 'Recursive delete (rm -rf)' },
54
+ { pattern: /\brm\s+/gi, label: 'File deletion (rm)' },
55
+ { pattern: /\bdel\s+/gi, label: 'File deletion (del)' },
56
+ { pattern: /\brmdir\s+/gi, label: 'Directory removal (rmdir)' },
57
+ { pattern: /powershell\s+-[Ee]ncoded[Cc]ommand/g, label: 'PowerShell encoded command' },
58
+ { pattern: /\bcurl\b.*\|\s*(?:sh|bash|zsh)\b/g, label: 'Curl piped to shell' },
59
+ { pattern: /\bwget\b.*\|\s*(?:sh|bash|zsh)\b/g, label: 'Wget piped to shell' },
60
+ { pattern: /\beval\s*\(/g, label: 'Dynamic eval execution' },
61
+ { pattern: /\bexec\s+/gi, label: 'Process execution (exec)' },
62
+ { pattern: /\bchmod\s+777\b/g, label: 'Overly permissive chmod 777' },
63
+ { pattern: /\bnet\s+user\b/gi, label: 'Windows user management (net user)' },
64
+ { pattern: /\breg\s+add\b/gi, label: 'Windows registry modification' },
65
+ ];
66
+ /** Patterns that indicate hardcoded API keys/tokens in MCP configs. */
67
+ const SECRET_PATTERNS = [
68
+ { regex: /sk-[A-Za-z0-9_-]{20,}/g, label: 'OpenAI API Key' },
69
+ { regex: /sk-ant-[A-Za-z0-9_-]{20,}/g, label: 'Anthropic API Key' },
70
+ { regex: /ghp_[A-Za-z0-9]{36,}/g, label: 'GitHub PAT' },
71
+ { regex: /AKIA[0-9A-Z]{16}/g, label: 'AWS Access Key' },
72
+ { regex: /glpat-[A-Za-z0-9_-]{20,}/g, label: 'GitLab PAT' },
73
+ { regex: /(?:api_key|apikey|secret|token|password|auth_token)\s*[=:]\s*["'][A-Za-z0-9_/+=.-]{10,}["']/gi, label: 'Hardcoded Credential' },
74
+ ];
75
+ /** Overly broad filesystem paths that grant too much access. */
76
+ const BROAD_FS_PATTERNS = [
77
+ { pattern: /[\"']\/[\"']/g, label: 'Root filesystem (/)' },
78
+ { pattern: /[\"']C:\\\\[\"']/gi, label: 'Root drive (C:\\)' },
79
+ { pattern: /[\"']~[\"']/g, label: 'Home directory (~)' },
80
+ { pattern: /[\"']\/home[\"']/g, label: 'All home directories (/home)' },
81
+ { pattern: /[\"']\/Users[\"']/g, label: 'All user directories (/Users)' },
82
+ { pattern: /[\"']\*[\"']/g, label: 'Wildcard glob (*)' },
83
+ ];
84
+ /** Maximum file size to scan (512KB — configs should be small). */
85
+ const MAX_CONFIG_SIZE = 512 * 1024;
86
+ /**
87
+ * Redacts sensitive content for safe display.
88
+ */
89
+ function redact(value) {
90
+ if (value.length <= 12)
91
+ return '****';
92
+ return value.substring(0, 4) + '****' + value.substring(value.length - 4);
93
+ }
94
+ /**
95
+ * Locates all MCP config files in common locations.
96
+ */
97
+ function findMCPConfigs(projectPath) {
98
+ const results = [];
99
+ const homeDir = os.homedir();
100
+ // Search locations: home dir, common config dirs, project dir
101
+ const searchRoots = [
102
+ homeDir,
103
+ path.join(homeDir, '.claude'),
104
+ path.join(homeDir, '.cursor'),
105
+ path.join(homeDir, '.config'),
106
+ path.join(homeDir, 'AppData', 'Roaming', 'Claude'),
107
+ path.join(homeDir, 'Library', 'Application Support', 'Claude'),
108
+ projectPath,
109
+ path.join(projectPath, '.claude'),
110
+ path.join(projectPath, '.cursor'),
111
+ ];
112
+ for (const root of searchRoots) {
113
+ if (!fs.existsSync(root))
114
+ continue;
115
+ for (const filename of MCP_CONFIG_FILENAMES) {
116
+ const filePath = path.join(root, filename);
117
+ try {
118
+ if (fs.existsSync(filePath)) {
119
+ const stat = fs.statSync(filePath);
120
+ if (stat.isFile() && stat.size <= MAX_CONFIG_SIZE && stat.size > 0) {
121
+ // Avoid duplicates
122
+ if (!results.includes(filePath)) {
123
+ results.push(filePath);
124
+ }
125
+ }
126
+ }
127
+ }
128
+ catch {
129
+ // Skip inaccessible files
130
+ }
131
+ }
132
+ }
133
+ return results;
134
+ }
135
+ /**
136
+ * MCPAuditor — Audits MCP server configurations for shell injection,
137
+ * over-privileged tool access, hardcoded secrets, insecure transport,
138
+ * and overly broad filesystem access.
139
+ */
140
+ class MCPAuditor {
141
+ name = 'MCPAuditor';
142
+ label = '📡 MCP Auditor';
143
+ async scan(options) {
144
+ const startTime = Date.now();
145
+ const findings = [];
146
+ const configFiles = findMCPConfigs(options.path);
147
+ for (const filePath of configFiles) {
148
+ let content;
149
+ try {
150
+ content = fs.readFileSync(filePath, 'utf-8');
151
+ }
152
+ catch {
153
+ continue; // Skip unreadable files
154
+ }
155
+ // Report MCP config discovery
156
+ findings.push({
157
+ module: this.name,
158
+ severity: types_1.Severity.INFO,
159
+ title: 'MCP Configuration Found',
160
+ description: `MCP configuration file detected at ${filePath}. Auditing for security issues.`,
161
+ filePath,
162
+ remediation: 'Periodically review MCP server configurations for security',
163
+ });
164
+ // Parse JSON to inspect structure
165
+ let config;
166
+ try {
167
+ config = JSON.parse(content);
168
+ }
169
+ catch {
170
+ findings.push({
171
+ module: this.name,
172
+ severity: types_1.Severity.LOW,
173
+ title: 'Malformed MCP Configuration',
174
+ description: 'Could not parse MCP config as valid JSON.',
175
+ filePath,
176
+ remediation: 'Fix JSON syntax errors in the MCP configuration',
177
+ });
178
+ continue;
179
+ }
180
+ // Check for shell injection in command args
181
+ for (const pattern of DANGEROUS_COMMANDS) {
182
+ pattern.pattern.lastIndex = 0;
183
+ let match;
184
+ while ((match = pattern.pattern.exec(content)) !== null) {
185
+ const upToMatch = content.substring(0, match.index);
186
+ const lineNumber = upToMatch.split('\n').length;
187
+ findings.push({
188
+ module: this.name,
189
+ severity: types_1.Severity.CRITICAL,
190
+ title: `Shell Injection Risk — ${pattern.label}`,
191
+ description: `Dangerous command pattern detected in MCP server configuration.`,
192
+ filePath,
193
+ line: lineNumber,
194
+ evidence: match[0],
195
+ remediation: 'Remove dangerous shell commands from MCP server arguments. Use dedicated tools instead of raw shell access.',
196
+ });
197
+ }
198
+ }
199
+ // Check for hardcoded API keys/tokens
200
+ for (const pattern of SECRET_PATTERNS) {
201
+ pattern.regex.lastIndex = 0;
202
+ let match;
203
+ while ((match = pattern.regex.exec(content)) !== null) {
204
+ const upToMatch = content.substring(0, match.index);
205
+ const lineNumber = upToMatch.split('\n').length;
206
+ findings.push({
207
+ module: this.name,
208
+ severity: types_1.Severity.CRITICAL,
209
+ title: `Hardcoded Secret in MCP Config — ${pattern.label}`,
210
+ description: `Found a potential ${pattern.label} hardcoded in MCP configuration.`,
211
+ filePath,
212
+ line: lineNumber,
213
+ evidence: redact(match[0]),
214
+ remediation: 'Use environment variables instead of hardcoding secrets in MCP configs',
215
+ });
216
+ }
217
+ }
218
+ // Check for overly broad filesystem access
219
+ for (const fsPattern of BROAD_FS_PATTERNS) {
220
+ fsPattern.pattern.lastIndex = 0;
221
+ let match;
222
+ while ((match = fsPattern.pattern.exec(content)) !== null) {
223
+ const upToMatch = content.substring(0, match.index);
224
+ const lineNumber = upToMatch.split('\n').length;
225
+ findings.push({
226
+ module: this.name,
227
+ severity: types_1.Severity.HIGH,
228
+ title: `Overly Broad Filesystem Access — ${fsPattern.label}`,
229
+ description: `MCP server is configured with access to ${fsPattern.label}, which grants excessive permissions.`,
230
+ filePath,
231
+ line: lineNumber,
232
+ evidence: match[0],
233
+ remediation: 'Restrict MCP server filesystem access to specific project directories only',
234
+ });
235
+ }
236
+ }
237
+ // Check for insecure stdio transport without validation
238
+ const mcpServers = config['mcpServers'] ??
239
+ config['servers'] ?? {};
240
+ if (typeof mcpServers === 'object' && mcpServers !== null) {
241
+ for (const [serverName, serverConfig] of Object.entries(mcpServers)) {
242
+ if (typeof serverConfig !== 'object' || serverConfig === null)
243
+ continue;
244
+ const sc = serverConfig;
245
+ // Check transport type
246
+ const transport = sc['transport'] ?? 'stdio';
247
+ if (transport === 'stdio') {
248
+ // stdio is default — check if there's any validation/sandboxing
249
+ const hasEnvRestriction = sc['env'] !== undefined;
250
+ const command = String(sc['command'] ?? '');
251
+ if (command && !hasEnvRestriction) {
252
+ findings.push({
253
+ module: this.name,
254
+ severity: types_1.Severity.MEDIUM,
255
+ title: `Stdio Transport Without Environment Restrictions — ${serverName}`,
256
+ description: `MCP server "${serverName}" uses stdio transport without explicit environment variable restrictions.`,
257
+ filePath,
258
+ remediation: 'Add explicit "env" configuration to restrict environment variable exposure to MCP servers',
259
+ });
260
+ }
261
+ }
262
+ // Check for over-privileged tool access (wildcard or excessive tool lists)
263
+ const tools = sc['tools'];
264
+ if (Array.isArray(tools)) {
265
+ if (tools.includes('*') || tools.includes('all')) {
266
+ findings.push({
267
+ module: this.name,
268
+ severity: types_1.Severity.HIGH,
269
+ title: `Over-Privileged Tool Access — ${serverName}`,
270
+ description: `MCP server "${serverName}" has wildcard tool access, granting it all available tools.`,
271
+ filePath,
272
+ remediation: 'Restrict tool access to only the specific tools the server needs',
273
+ });
274
+ }
275
+ }
276
+ }
277
+ }
278
+ }
279
+ return {
280
+ module: this.name,
281
+ label: this.label,
282
+ success: true,
283
+ durationMs: Date.now() - startTime,
284
+ itemsScanned: configFiles.length,
285
+ findings,
286
+ };
287
+ }
288
+ }
289
+ exports.MCPAuditor = MCPAuditor;
290
+ //# sourceMappingURL=mcp-auditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-auditor.js","sourceRoot":"","sources":["../../src/modules/mcp-auditor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { ScannerModule, ModuleResult, ScanOptions } from '../types';
2
+ /**
3
+ * PostureChecker — Audits developer workstation security posture
4
+ * including git config, .gitignore, .npmrc, SSH keys, and cloud credentials.
5
+ */
6
+ export declare class PostureChecker implements ScannerModule {
7
+ name: "PostureChecker";
8
+ label: string;
9
+ scan(options: ScanOptions): Promise<ModuleResult>;
10
+ }
11
+ //# sourceMappingURL=posture-checker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"posture-checker.d.ts","sourceRoot":"","sources":["../../src/modules/posture-checker.ts"],"names":[],"mappings":"AASA,OAAO,EACL,aAAa,EACb,YAAY,EAEZ,WAAW,EAEZ,MAAM,UAAU,CAAC;AAoClB;;;GAGG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,IAAI,EAAG,gBAAgB,CAAU;IACjC,KAAK,SAAwB;IAEvB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CA0OxD"}
@@ -0,0 +1,315 @@
1
+ "use strict";
2
+ // ============================================================
3
+ // DevArmor — Posture Checker Module
4
+ // Audits developer workstation security posture.
5
+ // ============================================================
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.PostureChecker = void 0;
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const os = __importStar(require("os"));
44
+ const child_process_1 = require("child_process");
45
+ const types_1 = require("../types");
46
+ /** Common personal email domains to flag. */
47
+ const PERSONAL_EMAIL_DOMAINS = [
48
+ 'gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com',
49
+ 'aol.com', 'icloud.com', 'mail.com', 'protonmail.com',
50
+ 'live.com', 'msn.com', 'ymail.com', 'zoho.com',
51
+ ];
52
+ /** Cloud CLI credential file locations relative to home directory. */
53
+ const CLOUD_CREDENTIAL_FILES = [
54
+ { name: 'AWS Credentials', file: path.join('.aws', 'credentials') },
55
+ { name: 'AWS Config', file: path.join('.aws', 'config') },
56
+ { name: 'Azure CLI Config', file: path.join('.azure', 'config') },
57
+ { name: 'Azure CLI Token', file: path.join('.azure', 'accessTokens.json') },
58
+ { name: 'Azure CLI Profile', file: path.join('.azure', 'azureProfile.json') },
59
+ { name: 'GCP Application Default Credentials', file: path.join('.config', 'gcloud', 'application_default_credentials.json') },
60
+ { name: 'GCP Properties', file: path.join('.config', 'gcloud', 'properties') },
61
+ ];
62
+ /** SSH key files to check. */
63
+ const SSH_KEY_FILES = [
64
+ 'id_rsa', 'id_ecdsa', 'id_ed25519', 'id_dsa',
65
+ ];
66
+ /**
67
+ * Safely executes a command and returns stdout, or null on failure.
68
+ */
69
+ function safeExec(command) {
70
+ try {
71
+ return (0, child_process_1.execSync)(command, { encoding: 'utf-8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'] }).trim();
72
+ }
73
+ catch {
74
+ return null;
75
+ }
76
+ }
77
+ /**
78
+ * PostureChecker — Audits developer workstation security posture
79
+ * including git config, .gitignore, .npmrc, SSH keys, and cloud credentials.
80
+ */
81
+ class PostureChecker {
82
+ name = 'PostureChecker';
83
+ label = '📋 Posture Checker';
84
+ async scan(options) {
85
+ const startTime = Date.now();
86
+ const findings = [];
87
+ const homeDir = os.homedir();
88
+ let itemsChecked = 0;
89
+ // ── Check 1: Git config email exposure ──
90
+ itemsChecked++;
91
+ const gitEmail = safeExec('git config --global user.email');
92
+ if (gitEmail) {
93
+ const domain = gitEmail.split('@')[1]?.toLowerCase();
94
+ if (domain && PERSONAL_EMAIL_DOMAINS.includes(domain)) {
95
+ findings.push({
96
+ module: this.name,
97
+ severity: types_1.Severity.MEDIUM,
98
+ title: 'Personal Email in Global Git Config',
99
+ description: `Global git config uses personal email "${gitEmail}". This email appears in every commit and is publicly visible on pushed repositories.`,
100
+ remediation: 'Use a work email or GitHub noreply address: git config --global user.email "user@users.noreply.github.com"',
101
+ });
102
+ }
103
+ else if (gitEmail) {
104
+ findings.push({
105
+ module: this.name,
106
+ severity: types_1.Severity.INFO,
107
+ title: 'Git Email Configured',
108
+ description: `Global git email is set to "${gitEmail}".`,
109
+ remediation: 'No action needed — verify this email is appropriate for public commits',
110
+ });
111
+ }
112
+ }
113
+ else {
114
+ findings.push({
115
+ module: this.name,
116
+ severity: types_1.Severity.LOW,
117
+ title: 'No Global Git Email Configured',
118
+ description: 'No global git user.email is set. Commits may use system defaults.',
119
+ remediation: 'Set a git email: git config --global user.email "your-email@example.com"',
120
+ });
121
+ }
122
+ // ── Check 2: .gitignore exists and covers .env ──
123
+ itemsChecked++;
124
+ const gitignorePath = path.join(options.path, '.gitignore');
125
+ if (fs.existsSync(gitignorePath)) {
126
+ let gitignoreContent;
127
+ try {
128
+ gitignoreContent = fs.readFileSync(gitignorePath, 'utf-8');
129
+ }
130
+ catch {
131
+ gitignoreContent = '';
132
+ }
133
+ const hasEnvEntry = /^\.env$/m.test(gitignoreContent) ||
134
+ /^\.env\.\*$/m.test(gitignoreContent) ||
135
+ /^\.env\.local$/m.test(gitignoreContent) ||
136
+ /^\.env\*$/m.test(gitignoreContent);
137
+ if (!hasEnvEntry) {
138
+ findings.push({
139
+ module: this.name,
140
+ severity: types_1.Severity.HIGH,
141
+ title: '.gitignore Missing .env Entry',
142
+ description: '.gitignore exists but does not contain entries for .env files. Environment files with secrets may be accidentally committed.',
143
+ filePath: gitignorePath,
144
+ remediation: 'Add ".env" and ".env.*" to your .gitignore file',
145
+ });
146
+ }
147
+ else {
148
+ findings.push({
149
+ module: this.name,
150
+ severity: types_1.Severity.INFO,
151
+ title: '.gitignore Covers .env Files',
152
+ description: '.gitignore properly includes entries for .env files.',
153
+ filePath: gitignorePath,
154
+ remediation: 'No action needed',
155
+ });
156
+ }
157
+ }
158
+ else {
159
+ findings.push({
160
+ module: this.name,
161
+ severity: types_1.Severity.HIGH,
162
+ title: 'No .gitignore File Found',
163
+ description: 'No .gitignore file exists in the project root. Sensitive files may be accidentally committed.',
164
+ remediation: 'Create a .gitignore file with entries for .env, node_modules, and other sensitive paths',
165
+ });
166
+ }
167
+ // ── Check 3: .npmrc for auth tokens ──
168
+ itemsChecked++;
169
+ const npmrcPaths = [
170
+ path.join(options.path, '.npmrc'),
171
+ path.join(homeDir, '.npmrc'),
172
+ ];
173
+ for (const npmrcPath of npmrcPaths) {
174
+ if (!fs.existsSync(npmrcPath))
175
+ continue;
176
+ let npmrcContent;
177
+ try {
178
+ npmrcContent = fs.readFileSync(npmrcPath, 'utf-8');
179
+ }
180
+ catch {
181
+ continue;
182
+ }
183
+ // Check for _authToken
184
+ const authTokenMatch = /_authToken\s*=\s*(.+)/i.exec(npmrcContent);
185
+ if (authTokenMatch) {
186
+ const token = authTokenMatch[1].trim();
187
+ const isEnvVar = token.startsWith('${') && token.endsWith('}');
188
+ if (!isEnvVar) {
189
+ const upToMatch = npmrcContent.substring(0, authTokenMatch.index);
190
+ const lineNumber = upToMatch.split('\n').length;
191
+ findings.push({
192
+ module: this.name,
193
+ severity: types_1.Severity.HIGH,
194
+ title: 'Hardcoded npm Auth Token',
195
+ description: `Found a hardcoded _authToken in .npmrc. This token should use environment variable substitution.`,
196
+ filePath: npmrcPath,
197
+ line: lineNumber,
198
+ evidence: '_authToken=****',
199
+ remediation: 'Replace the hardcoded token with an env var: _authToken=${NPM_TOKEN}',
200
+ });
201
+ }
202
+ else {
203
+ findings.push({
204
+ module: this.name,
205
+ severity: types_1.Severity.INFO,
206
+ title: 'npm Auth Token Uses Environment Variable',
207
+ description: '.npmrc uses environment variable substitution for auth token.',
208
+ filePath: npmrcPath,
209
+ remediation: 'No action needed',
210
+ });
211
+ }
212
+ }
213
+ }
214
+ // ── Check 4: SSH key file existence ──
215
+ itemsChecked++;
216
+ const sshDir = path.join(homeDir, '.ssh');
217
+ if (fs.existsSync(sshDir)) {
218
+ for (const keyFile of SSH_KEY_FILES) {
219
+ const keyPath = path.join(sshDir, keyFile);
220
+ if (!fs.existsSync(keyPath))
221
+ continue;
222
+ // On non-Windows, we'd check permissions with stat
223
+ // On Windows, report existence and recommend review
224
+ const isWindows = os.platform() === 'win32';
225
+ if (isWindows) {
226
+ findings.push({
227
+ module: this.name,
228
+ severity: types_1.Severity.INFO,
229
+ title: `SSH Private Key Found — ${keyFile}`,
230
+ description: `SSH private key file detected at ${keyPath}. Verify that file ACLs are properly restricted.`,
231
+ filePath: keyPath,
232
+ remediation: 'Ensure only your user account has access: icacls <key> /inheritance:r /grant:r "%USERNAME%:R"',
233
+ });
234
+ }
235
+ else {
236
+ // Check Unix permissions
237
+ try {
238
+ const stat = fs.statSync(keyPath);
239
+ const mode = (stat.mode & 0o777).toString(8);
240
+ const isPermissive = (stat.mode & 0o077) !== 0; // group/other have any access
241
+ if (isPermissive) {
242
+ findings.push({
243
+ module: this.name,
244
+ severity: types_1.Severity.HIGH,
245
+ title: `SSH Key Overly Permissive — ${keyFile}`,
246
+ description: `SSH private key has permissions ${mode} — group/other users can read it.`,
247
+ filePath: keyPath,
248
+ evidence: `mode: ${mode}`,
249
+ remediation: `Fix permissions: chmod 600 ${keyPath}`,
250
+ });
251
+ }
252
+ else {
253
+ findings.push({
254
+ module: this.name,
255
+ severity: types_1.Severity.INFO,
256
+ title: `SSH Key Permissions OK — ${keyFile}`,
257
+ description: `SSH private key has proper permissions (${mode}).`,
258
+ filePath: keyPath,
259
+ remediation: 'No action needed',
260
+ });
261
+ }
262
+ }
263
+ catch {
264
+ // Skip inaccessible key files
265
+ }
266
+ }
267
+ }
268
+ }
269
+ // ── Check 5: Cloud CLI credential files ──
270
+ itemsChecked++;
271
+ for (const cred of CLOUD_CREDENTIAL_FILES) {
272
+ const credPath = path.join(homeDir, cred.file);
273
+ if (!fs.existsSync(credPath))
274
+ continue;
275
+ findings.push({
276
+ module: this.name,
277
+ severity: types_1.Severity.MEDIUM,
278
+ title: `Cloud CLI Credentials Found — ${cred.name}`,
279
+ description: `Cloud credential file detected at ${credPath}. Ensure these credentials follow least-privilege principles.`,
280
+ filePath: credPath,
281
+ remediation: 'Review cloud CLI credentials for excessive permissions. Use short-lived tokens or SSO where possible.',
282
+ });
283
+ // Additionally check AWS credentials for hardcoded keys
284
+ if (cred.file.includes('.aws') && cred.file.endsWith('credentials')) {
285
+ let content;
286
+ try {
287
+ content = fs.readFileSync(credPath, 'utf-8');
288
+ }
289
+ catch {
290
+ continue;
291
+ }
292
+ if (/aws_access_key_id\s*=\s*AKIA[0-9A-Z]{16}/i.test(content)) {
293
+ findings.push({
294
+ module: this.name,
295
+ severity: types_1.Severity.HIGH,
296
+ title: 'Long-Lived AWS Access Key Detected',
297
+ description: 'AWS credentials file contains a long-lived access key. Consider using IAM Identity Center (SSO) instead.',
298
+ filePath: credPath,
299
+ remediation: 'Migrate to AWS SSO/IAM Identity Center for short-lived credentials',
300
+ });
301
+ }
302
+ }
303
+ }
304
+ return {
305
+ module: this.name,
306
+ label: this.label,
307
+ success: true,
308
+ durationMs: Date.now() - startTime,
309
+ itemsScanned: itemsChecked,
310
+ findings,
311
+ };
312
+ }
313
+ }
314
+ exports.PostureChecker = PostureChecker;
315
+ //# sourceMappingURL=posture-checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"posture-checker.js","sourceRoot":"","sources":["../../src/modules/posture-checker.ts"],"names":[],"mappings":"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"}