codeslick-cli 1.4.0 → 1.4.2
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/dist/packages/cli/src/commands/scan.d.ts.map +1 -1
- package/dist/packages/cli/src/commands/scan.js +7 -3
- package/dist/packages/cli/src/commands/scan.js.map +1 -1
- package/dist/packages/cli/src/reporters/cli-reporter.d.ts +11 -0
- package/dist/packages/cli/src/reporters/cli-reporter.d.ts.map +1 -1
- package/dist/packages/cli/src/reporters/cli-reporter.js +150 -45
- package/dist/packages/cli/src/reporters/cli-reporter.js.map +1 -1
- package/dist/packages/cli/src/scanner/local-scanner.d.ts +2 -2
- package/dist/packages/cli/src/scanner/local-scanner.d.ts.map +1 -1
- package/dist/packages/cli/src/scanner/local-scanner.js +40 -9
- package/dist/packages/cli/src/scanner/local-scanner.js.map +1 -1
- package/dist/src/lib/analyzers/go-analyzer.d.ts +12 -0
- package/dist/src/lib/analyzers/go-analyzer.d.ts.map +1 -1
- package/dist/src/lib/analyzers/go-analyzer.js +113 -0
- package/dist/src/lib/analyzers/go-analyzer.js.map +1 -1
- package/dist/src/lib/analyzers/iac/pii-detector.d.ts +27 -0
- package/dist/src/lib/analyzers/iac/pii-detector.d.ts.map +1 -0
- package/dist/src/lib/analyzers/iac/pii-detector.js +199 -0
- package/dist/src/lib/analyzers/iac/pii-detector.js.map +1 -0
- package/dist/src/lib/analyzers/iac/pii-patterns.d.ts +43 -0
- package/dist/src/lib/analyzers/iac/pii-patterns.d.ts.map +1 -0
- package/dist/src/lib/analyzers/iac/pii-patterns.js +228 -0
- package/dist/src/lib/analyzers/iac/pii-patterns.js.map +1 -0
- package/dist/src/lib/analyzers/java-analyzer.d.ts +5 -0
- package/dist/src/lib/analyzers/java-analyzer.d.ts.map +1 -1
- package/dist/src/lib/analyzers/java-analyzer.js +51 -0
- package/dist/src/lib/analyzers/java-analyzer.js.map +1 -1
- package/dist/src/lib/analyzers/javascript/quality-checks/ai-hallucinations.d.ts +8 -4
- package/dist/src/lib/analyzers/javascript/quality-checks/ai-hallucinations.d.ts.map +1 -1
- package/dist/src/lib/analyzers/javascript/quality-checks/ai-hallucinations.js +109 -13
- package/dist/src/lib/analyzers/javascript/quality-checks/ai-hallucinations.js.map +1 -1
- package/dist/src/lib/analyzers/javascript/quality-checks/reference-errors.d.ts.map +1 -1
- package/dist/src/lib/analyzers/javascript/quality-checks/reference-errors.js +7 -8
- package/dist/src/lib/analyzers/javascript/quality-checks/reference-errors.js.map +1 -1
- package/dist/src/lib/analyzers/javascript-analyzer.d.ts.map +1 -1
- package/dist/src/lib/analyzers/javascript-analyzer.js +16 -12
- package/dist/src/lib/analyzers/javascript-analyzer.js.map +1 -1
- package/dist/src/lib/analyzers/kubernetes/checks/network-security.d.ts +33 -0
- package/dist/src/lib/analyzers/kubernetes/checks/network-security.d.ts.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/checks/network-security.js +184 -0
- package/dist/src/lib/analyzers/kubernetes/checks/network-security.js.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/checks/pod-security.d.ts +60 -0
- package/dist/src/lib/analyzers/kubernetes/checks/pod-security.d.ts.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/checks/pod-security.js +418 -0
- package/dist/src/lib/analyzers/kubernetes/checks/pod-security.js.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/checks/rbac-security.d.ts +44 -0
- package/dist/src/lib/analyzers/kubernetes/checks/rbac-security.d.ts.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/checks/rbac-security.js +275 -0
- package/dist/src/lib/analyzers/kubernetes/checks/rbac-security.js.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/checks/resource-management.d.ts +32 -0
- package/dist/src/lib/analyzers/kubernetes/checks/resource-management.d.ts.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/checks/resource-management.js +176 -0
- package/dist/src/lib/analyzers/kubernetes/checks/resource-management.js.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/checks/secrets-management.d.ts +38 -0
- package/dist/src/lib/analyzers/kubernetes/checks/secrets-management.d.ts.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/checks/secrets-management.js +266 -0
- package/dist/src/lib/analyzers/kubernetes/checks/secrets-management.js.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/checks/service-security.d.ts +26 -0
- package/dist/src/lib/analyzers/kubernetes/checks/service-security.d.ts.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/checks/service-security.js +120 -0
- package/dist/src/lib/analyzers/kubernetes/checks/service-security.js.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/parser.d.ts +74 -0
- package/dist/src/lib/analyzers/kubernetes/parser.d.ts.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/parser.js +233 -0
- package/dist/src/lib/analyzers/kubernetes/parser.js.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/pii-detector.d.ts +34 -0
- package/dist/src/lib/analyzers/kubernetes/pii-detector.d.ts.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/pii-detector.js +182 -0
- package/dist/src/lib/analyzers/kubernetes/pii-detector.js.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/types.d.ts +266 -0
- package/dist/src/lib/analyzers/kubernetes/types.d.ts.map +1 -0
- package/dist/src/lib/analyzers/kubernetes/types.js +77 -0
- package/dist/src/lib/analyzers/kubernetes/types.js.map +1 -0
- package/dist/src/lib/analyzers/kubernetes-analyzer.d.ts +93 -0
- package/dist/src/lib/analyzers/kubernetes-analyzer.d.ts.map +1 -0
- package/dist/src/lib/analyzers/kubernetes-analyzer.js +215 -0
- package/dist/src/lib/analyzers/kubernetes-analyzer.js.map +1 -0
- package/dist/src/lib/analyzers/python-analyzer.d.ts.map +1 -1
- package/dist/src/lib/analyzers/python-analyzer.js +32 -48
- package/dist/src/lib/analyzers/python-analyzer.js.map +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/api-keys/ai-providers.d.ts +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/api-keys/ai-providers.d.ts.map +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/api-keys/aws.d.ts +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/api-keys/aws.d.ts.map +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/api-keys/cloud-providers.d.ts +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/api-keys/cloud-providers.d.ts.map +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/api-keys/communication.d.ts +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/api-keys/communication.d.ts.map +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/api-keys/generic.d.ts +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/api-keys/generic.d.ts.map +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/api-keys/github.d.ts +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/api-keys/github.d.ts.map +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/api-keys/stripe.d.ts +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/api-keys/stripe.d.ts.map +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/api-keys.d.ts +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/api-keys.d.ts.map +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/credentials.d.ts +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/credentials.d.ts.map +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/private-keys.d.ts +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/private-keys.d.ts.map +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/tokens.d.ts +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/tokens.d.ts.map +1 -1
- package/dist/src/lib/analyzers/secrets/secrets-analyzer.d.ts +2 -32
- package/dist/src/lib/analyzers/secrets/secrets-analyzer.d.ts.map +1 -1
- package/dist/src/lib/analyzers/secrets/secrets-analyzer.js.map +1 -1
- package/dist/src/lib/analyzers/secrets/types.d.ts +40 -0
- package/dist/src/lib/analyzers/secrets/types.d.ts.map +1 -0
- package/dist/src/lib/analyzers/secrets/types.js +10 -0
- package/dist/src/lib/analyzers/secrets/types.js.map +1 -0
- package/dist/src/lib/analyzers/terraform-analyzer.d.ts +1 -0
- package/dist/src/lib/analyzers/terraform-analyzer.d.ts.map +1 -1
- package/dist/src/lib/analyzers/terraform-analyzer.js +28 -0
- package/dist/src/lib/analyzers/terraform-analyzer.js.map +1 -1
- package/dist/src/lib/analyzers/typescript-analyzer.d.ts +5 -0
- package/dist/src/lib/analyzers/typescript-analyzer.d.ts.map +1 -1
- package/dist/src/lib/analyzers/typescript-analyzer.js +76 -0
- package/dist/src/lib/analyzers/typescript-analyzer.js.map +1 -1
- package/dist/src/lib/analyzers/utils/false-positive-filter.d.ts +27 -0
- package/dist/src/lib/analyzers/utils/false-positive-filter.d.ts.map +1 -0
- package/dist/src/lib/analyzers/utils/false-positive-filter.js +176 -0
- package/dist/src/lib/analyzers/utils/false-positive-filter.js.map +1 -0
- package/dist/src/lib/security/epss-service.d.ts.map +1 -1
- package/dist/src/lib/security/epss-service.js +27 -8
- package/dist/src/lib/security/epss-service.js.map +1 -1
- package/dist/src/lib/security/severity-scoring.d.ts.map +1 -1
- package/dist/src/lib/security/severity-scoring.js +24 -0
- package/dist/src/lib/security/severity-scoring.js.map +1 -1
- package/dist/src/lib/types/index.d.ts +3 -3
- package/dist/src/lib/types/index.d.ts.map +1 -1
- package/dist/src/lib/utils/ignore-patterns.d.ts +60 -0
- package/dist/src/lib/utils/ignore-patterns.d.ts.map +1 -0
- package/dist/src/lib/utils/ignore-patterns.js +212 -0
- package/dist/src/lib/utils/ignore-patterns.js.map +1 -0
- package/package.json +1 -1
- package/src/commands/scan.ts +7 -3
- package/src/reporters/cli-reporter.ts +174 -48
- package/src/scanner/local-scanner.ts +54 -10
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Kubernetes Secrets Management Checks
|
|
4
|
+
*
|
|
5
|
+
* WR3 Week 6: 4 High/Medium Severity Secrets Management Checks
|
|
6
|
+
* - Hardcoded secrets in ConfigMaps
|
|
7
|
+
* - Secrets in environment variables
|
|
8
|
+
* - Secrets mounted without readOnly
|
|
9
|
+
* - Base64-encoded secrets in YAML
|
|
10
|
+
*
|
|
11
|
+
* Created: February 5, 2026
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.checkHardcodedSecretsInConfigMaps = checkHardcodedSecretsInConfigMaps;
|
|
15
|
+
exports.checkSecretsInEnvVars = checkSecretsInEnvVars;
|
|
16
|
+
exports.checkSecretVolumesWritable = checkSecretVolumesWritable;
|
|
17
|
+
exports.checkBase64SecretsInYAML = checkBase64SecretsInYAML;
|
|
18
|
+
exports.runSecretsManagementChecks = runSecretsManagementChecks;
|
|
19
|
+
const parser_1 = require("../parser");
|
|
20
|
+
// Common secret patterns to detect in ConfigMaps and environment variables
|
|
21
|
+
const SECRET_PATTERNS = [
|
|
22
|
+
{ name: 'password', regex: /password\s*[:=]\s*["']?[^\s"']+/i },
|
|
23
|
+
{ name: 'api_key', regex: /api[_-]?key\s*[:=]\s*["']?[^\s"']+/i },
|
|
24
|
+
{ name: 'token', regex: /token\s*[:=]\s*["']?[^\s"']+/i },
|
|
25
|
+
{ name: 'secret', regex: /secret\s*[:=]\s*["']?[^\s"']+/i },
|
|
26
|
+
{ name: 'private_key', regex: /private[_-]?key\s*[:=]\s*["']?[^\s"']+/i },
|
|
27
|
+
{ name: 'access_key', regex: /access[_-]?key\s*[:=]\s*["']?[^\s"']+/i },
|
|
28
|
+
];
|
|
29
|
+
/**
|
|
30
|
+
* Check #14: Hardcoded Secrets in ConfigMaps (High - CVSS 7.5)
|
|
31
|
+
* Detects sensitive data patterns in ConfigMap data fields
|
|
32
|
+
*/
|
|
33
|
+
function checkHardcodedSecretsInConfigMaps(resource) {
|
|
34
|
+
if (resource.kind !== 'ConfigMap') {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const data = resource.data || {};
|
|
38
|
+
const foundSecrets = [];
|
|
39
|
+
// Scan ConfigMap data for secret patterns
|
|
40
|
+
for (const [key, value] of Object.entries(data)) {
|
|
41
|
+
const lowerKey = key.toLowerCase();
|
|
42
|
+
const lowerValue = value.toLowerCase();
|
|
43
|
+
// Check if key or value contains secret patterns
|
|
44
|
+
for (const pattern of SECRET_PATTERNS) {
|
|
45
|
+
if (lowerKey.includes(pattern.name) ||
|
|
46
|
+
pattern.regex.test(lowerValue) ||
|
|
47
|
+
pattern.regex.test(key)) {
|
|
48
|
+
foundSecrets.push(key);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (foundSecrets.length > 0) {
|
|
54
|
+
return {
|
|
55
|
+
severity: 'high',
|
|
56
|
+
message: `Hardcoded secrets detected in ConfigMap ${(0, parser_1.getResourceIdentifier)(resource)}: ${foundSecrets.join(', ')}`,
|
|
57
|
+
suggestion: 'Use Kubernetes Secrets instead of ConfigMaps for sensitive data. ConfigMaps are not designed for secret storage.',
|
|
58
|
+
category: 'kubernetes-configmap-secrets',
|
|
59
|
+
cvssScore: 7.5,
|
|
60
|
+
exploitLikelihood: 'high',
|
|
61
|
+
impact: 'data-breach',
|
|
62
|
+
owasp: 'A02:2021',
|
|
63
|
+
cwe: 'CWE-798',
|
|
64
|
+
attackVector: {
|
|
65
|
+
description: 'ConfigMaps are stored unencrypted in etcd and can be read by anyone with namespace access.',
|
|
66
|
+
exploitExample: 'Attacker gains namespace access → Lists ConfigMaps → Extracts hardcoded credentials → Accesses external services',
|
|
67
|
+
realWorldImpact: [
|
|
68
|
+
'Credentials stored in plain text',
|
|
69
|
+
'Exposed in etcd backups',
|
|
70
|
+
'Visible to all namespace users',
|
|
71
|
+
'No encryption at rest by default',
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
remediation: {
|
|
75
|
+
before: `apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: app-config\ndata:\n api_key: "sk-1234567890abcdef"`,
|
|
76
|
+
after: `apiVersion: v1\nkind: Secret\nmetadata:\n name: app-secrets\ntype: Opaque\nstringData:\n api_key: "sk-1234567890abcdef" # Better: use external secret manager`,
|
|
77
|
+
explanation: 'Migrate sensitive data to Kubernetes Secrets (minimum) or preferably use external secret managers (Vault, AWS Secrets Manager).',
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Check #15: Secrets in Environment Variables (High - CVSS 7.0)
|
|
85
|
+
* Detects containers with environment variables containing plain-text secrets
|
|
86
|
+
*/
|
|
87
|
+
function checkSecretsInEnvVars(resource) {
|
|
88
|
+
const podSpec = (0, parser_1.getPodSpec)(resource);
|
|
89
|
+
if (!podSpec)
|
|
90
|
+
return null;
|
|
91
|
+
const containers = [...(podSpec.containers || []), ...(podSpec.initContainers || [])];
|
|
92
|
+
const vulnerableContainers = [];
|
|
93
|
+
for (const container of containers) {
|
|
94
|
+
const env = container.env || [];
|
|
95
|
+
const secretEnvVars = [];
|
|
96
|
+
for (const envVar of env) {
|
|
97
|
+
// Skip if using valueFrom (good practice - references Secret)
|
|
98
|
+
if (envVar.valueFrom) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
// Check if env var has a plain-text value that looks like a secret
|
|
102
|
+
if (envVar.value) {
|
|
103
|
+
const lowerName = envVar.name.toLowerCase();
|
|
104
|
+
const lowerValue = envVar.value.toLowerCase();
|
|
105
|
+
for (const pattern of SECRET_PATTERNS) {
|
|
106
|
+
if (lowerName.includes(pattern.name) || pattern.regex.test(lowerValue)) {
|
|
107
|
+
secretEnvVars.push(envVar.name);
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (secretEnvVars.length > 0) {
|
|
114
|
+
vulnerableContainers.push({ name: container.name, envVars: secretEnvVars });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (vulnerableContainers.length > 0) {
|
|
118
|
+
const details = vulnerableContainers
|
|
119
|
+
.map(c => `${c.name} (${c.envVars.join(', ')})`)
|
|
120
|
+
.join('; ');
|
|
121
|
+
return {
|
|
122
|
+
severity: 'high',
|
|
123
|
+
message: `Plain-text secrets in environment variables detected in ${(0, parser_1.getResourceIdentifier)(resource)}: ${details}`,
|
|
124
|
+
suggestion: 'Use env.valueFrom.secretKeyRef to reference Secrets instead of hardcoding values in env.value.',
|
|
125
|
+
category: 'kubernetes-env-secrets',
|
|
126
|
+
cvssScore: 7.0,
|
|
127
|
+
exploitLikelihood: 'high',
|
|
128
|
+
impact: 'data-breach',
|
|
129
|
+
owasp: 'A02:2021',
|
|
130
|
+
cwe: 'CWE-798',
|
|
131
|
+
attackVector: {
|
|
132
|
+
description: 'Environment variables are visible in container inspect, process listings, and logs.',
|
|
133
|
+
exploitExample: 'Attacker accesses container → Runs "env" command → Extracts secret values → Compromises external services',
|
|
134
|
+
realWorldImpact: [
|
|
135
|
+
'Secrets visible in container runtime',
|
|
136
|
+
'Exposed in crash dumps and logs',
|
|
137
|
+
'Readable via /proc/[pid]/environ',
|
|
138
|
+
'Stored in image layer metadata',
|
|
139
|
+
],
|
|
140
|
+
},
|
|
141
|
+
remediation: {
|
|
142
|
+
before: `env:\n - name: DATABASE_PASSWORD\n value: "hardcoded-password-123"`,
|
|
143
|
+
after: `env:\n - name: DATABASE_PASSWORD\n valueFrom:\n secretKeyRef:\n name: db-credentials\n key: password`,
|
|
144
|
+
explanation: 'Reference secrets using valueFrom.secretKeyRef instead of hardcoding values.',
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Check #16: Secrets Mounted Without ReadOnly (Medium - CVSS 6.0)
|
|
152
|
+
* Detects secret volumes mounted without readOnly: true
|
|
153
|
+
*/
|
|
154
|
+
function checkSecretVolumesWritable(resource) {
|
|
155
|
+
const podSpec = (0, parser_1.getPodSpec)(resource);
|
|
156
|
+
if (!podSpec)
|
|
157
|
+
return null;
|
|
158
|
+
const volumes = podSpec.volumes || [];
|
|
159
|
+
const secretVolumeNames = volumes
|
|
160
|
+
.filter((v) => v.secret)
|
|
161
|
+
.map((v) => v.name);
|
|
162
|
+
if (secretVolumeNames.length === 0) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
const containers = [...(podSpec.containers || []), ...(podSpec.initContainers || [])];
|
|
166
|
+
const writableSecretMounts = [];
|
|
167
|
+
for (const container of containers) {
|
|
168
|
+
const volumeMounts = container.volumeMounts || [];
|
|
169
|
+
for (const mount of volumeMounts) {
|
|
170
|
+
if (secretVolumeNames.includes(mount.name) && mount.readOnly !== true) {
|
|
171
|
+
writableSecretMounts.push(`${container.name}:${mount.mountPath}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (writableSecretMounts.length > 0) {
|
|
176
|
+
return {
|
|
177
|
+
severity: 'medium',
|
|
178
|
+
message: `Secret volumes mounted without readOnly in ${(0, parser_1.getResourceIdentifier)(resource)}: ${writableSecretMounts.join(', ')}`,
|
|
179
|
+
suggestion: 'Set readOnly: true for all secret volume mounts to prevent tampering.',
|
|
180
|
+
category: 'kubernetes-secret-volume-writable',
|
|
181
|
+
cvssScore: 6.0,
|
|
182
|
+
exploitLikelihood: 'medium',
|
|
183
|
+
impact: 'data-tampering',
|
|
184
|
+
owasp: 'A04:2021',
|
|
185
|
+
cwe: 'CWE-732',
|
|
186
|
+
attackVector: {
|
|
187
|
+
description: 'Writable secret mounts allow attackers to modify secret files, potentially creating backdoors or corrupting credentials.',
|
|
188
|
+
exploitExample: 'Attacker compromises container → Modifies mounted secret file → Application uses tampered credentials → Data exfiltration',
|
|
189
|
+
realWorldImpact: [
|
|
190
|
+
'Secret file modification',
|
|
191
|
+
'Credential tampering',
|
|
192
|
+
'Backdoor injection in certificates',
|
|
193
|
+
'Authentication bypass',
|
|
194
|
+
],
|
|
195
|
+
},
|
|
196
|
+
remediation: {
|
|
197
|
+
before: `volumeMounts:\n - name: app-secrets\n mountPath: /etc/secrets`,
|
|
198
|
+
after: `volumeMounts:\n - name: app-secrets\n mountPath: /etc/secrets\n readOnly: true`,
|
|
199
|
+
explanation: 'Always mount secret volumes as read-only to prevent tampering.',
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Check #17: Base64-Encoded Secrets in YAML (Medium - CVSS 5.5)
|
|
207
|
+
* Detects Secret resources with base64 data that may contain sensitive patterns
|
|
208
|
+
*/
|
|
209
|
+
function checkBase64SecretsInYAML(resource) {
|
|
210
|
+
if (resource.kind !== 'Secret') {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
const data = resource.data || {};
|
|
214
|
+
const stringData = resource.stringData || {};
|
|
215
|
+
// Check if secret has data (which is base64-encoded in YAML source)
|
|
216
|
+
// This is a warning that secrets are visible in YAML files
|
|
217
|
+
if (Object.keys(data).length > 0 || Object.keys(stringData).length > 0) {
|
|
218
|
+
return {
|
|
219
|
+
severity: 'medium',
|
|
220
|
+
message: `Base64-encoded secrets detected in YAML manifest for ${(0, parser_1.getResourceIdentifier)(resource)}`,
|
|
221
|
+
suggestion: 'Avoid committing Secret YAML to version control. Use external secret managers (Sealed Secrets, External Secrets Operator, Vault).',
|
|
222
|
+
category: 'kubernetes-secret-in-yaml',
|
|
223
|
+
cvssScore: 5.5,
|
|
224
|
+
exploitLikelihood: 'medium',
|
|
225
|
+
impact: 'data-breach',
|
|
226
|
+
owasp: 'A02:2021',
|
|
227
|
+
cwe: 'CWE-312',
|
|
228
|
+
attackVector: {
|
|
229
|
+
description: 'Base64 is encoding, not encryption. Secrets in YAML files are easily decoded and exposed via version control.',
|
|
230
|
+
exploitExample: 'Developer commits Secret YAML to git → Attacker accesses repository → Base64-decodes secret values → Gains credentials',
|
|
231
|
+
realWorldImpact: [
|
|
232
|
+
'Secrets exposed in version control',
|
|
233
|
+
'Base64 easily decoded (not encrypted)',
|
|
234
|
+
'Visible in git history forever',
|
|
235
|
+
'Accessible to all repository users',
|
|
236
|
+
],
|
|
237
|
+
},
|
|
238
|
+
remediation: {
|
|
239
|
+
before: `apiVersion: v1\nkind: Secret\nmetadata:\n name: app-secrets\ndata:\n password: cGFzc3dvcmQxMjM= # Visible in git!`,
|
|
240
|
+
after: `# Install Sealed Secrets or External Secrets Operator\n# Use kubectl create secret to create at runtime\n# Never commit Secret YAML to version control`,
|
|
241
|
+
explanation: 'Use Sealed Secrets (bitnami-labs/sealed-secrets) or External Secrets Operator to manage secrets securely without exposing them in YAML.',
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Run all secrets management checks on a resource
|
|
249
|
+
*/
|
|
250
|
+
function runSecretsManagementChecks(resource) {
|
|
251
|
+
const vulnerabilities = [];
|
|
252
|
+
const checks = [
|
|
253
|
+
checkHardcodedSecretsInConfigMaps,
|
|
254
|
+
checkSecretsInEnvVars,
|
|
255
|
+
checkSecretVolumesWritable,
|
|
256
|
+
checkBase64SecretsInYAML,
|
|
257
|
+
];
|
|
258
|
+
for (const check of checks) {
|
|
259
|
+
const vuln = check(resource);
|
|
260
|
+
if (vuln) {
|
|
261
|
+
vulnerabilities.push(vuln);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return vulnerabilities;
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=secrets-management.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets-management.js","sourceRoot":"","sources":["../../../../../../../../src/lib/analyzers/kubernetes/checks/secrets-management.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kubernetes Service Security Checks
|
|
3
|
+
*
|
|
4
|
+
* WR3 Week 6: 2 Medium Severity Service Security Checks
|
|
5
|
+
* - Missing liveness probes
|
|
6
|
+
* - Missing readiness probes
|
|
7
|
+
*
|
|
8
|
+
* Created: February 5, 2026
|
|
9
|
+
*/
|
|
10
|
+
import { SecurityVulnerability } from '../../types';
|
|
11
|
+
import type { KubernetesResource } from '../types';
|
|
12
|
+
/**
|
|
13
|
+
* Check #24: Missing Liveness Probes (Medium - CVSS 5.0)
|
|
14
|
+
* Detects containers without liveness probes
|
|
15
|
+
*/
|
|
16
|
+
export declare function checkMissingLivenessProbe(resource: KubernetesResource): SecurityVulnerability | null;
|
|
17
|
+
/**
|
|
18
|
+
* Check #25: Missing Readiness Probes (Medium - CVSS 5.0)
|
|
19
|
+
* Detects containers without readiness probes
|
|
20
|
+
*/
|
|
21
|
+
export declare function checkMissingReadinessProbe(resource: KubernetesResource): SecurityVulnerability | null;
|
|
22
|
+
/**
|
|
23
|
+
* Run all service security checks on a resource
|
|
24
|
+
*/
|
|
25
|
+
export declare function runServiceSecurityChecks(resource: KubernetesResource): SecurityVulnerability[];
|
|
26
|
+
//# sourceMappingURL=service-security.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-security.d.ts","sourceRoot":"","sources":["../../../../../../../../src/lib/analyzers/kubernetes/checks/service-security.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAa,MAAM,UAAU,CAAC;AAG9D;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,kBAAkB,GAC3B,qBAAqB,GAAG,IAAI,CA2C9B;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,kBAAkB,GAC3B,qBAAqB,GAAG,IAAI,CA2C9B;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,qBAAqB,EAAE,CAa9F"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Kubernetes Service Security Checks
|
|
4
|
+
*
|
|
5
|
+
* WR3 Week 6: 2 Medium Severity Service Security Checks
|
|
6
|
+
* - Missing liveness probes
|
|
7
|
+
* - Missing readiness probes
|
|
8
|
+
*
|
|
9
|
+
* Created: February 5, 2026
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.checkMissingLivenessProbe = checkMissingLivenessProbe;
|
|
13
|
+
exports.checkMissingReadinessProbe = checkMissingReadinessProbe;
|
|
14
|
+
exports.runServiceSecurityChecks = runServiceSecurityChecks;
|
|
15
|
+
const parser_1 = require("../parser");
|
|
16
|
+
/**
|
|
17
|
+
* Check #24: Missing Liveness Probes (Medium - CVSS 5.0)
|
|
18
|
+
* Detects containers without liveness probes
|
|
19
|
+
*/
|
|
20
|
+
function checkMissingLivenessProbe(resource) {
|
|
21
|
+
const podSpec = (0, parser_1.getPodSpec)(resource);
|
|
22
|
+
if (!podSpec)
|
|
23
|
+
return null;
|
|
24
|
+
const containers = podSpec.containers || [];
|
|
25
|
+
const missingProbes = [];
|
|
26
|
+
for (const container of containers) {
|
|
27
|
+
if (!container.livenessProbe) {
|
|
28
|
+
missingProbes.push(container.name);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (missingProbes.length > 0) {
|
|
32
|
+
return {
|
|
33
|
+
severity: 'medium',
|
|
34
|
+
message: `Containers without liveness probes in ${(0, parser_1.getResourceIdentifier)(resource)}: ${missingProbes.join(', ')}`,
|
|
35
|
+
suggestion: 'Add livenessProbe to detect and restart unhealthy containers automatically.',
|
|
36
|
+
category: 'kubernetes-missing-liveness-probe',
|
|
37
|
+
cvssScore: 5.0,
|
|
38
|
+
exploitLikelihood: 'medium',
|
|
39
|
+
impact: 'availability',
|
|
40
|
+
owasp: 'A04:2021',
|
|
41
|
+
cwe: 'CWE-400',
|
|
42
|
+
attackVector: {
|
|
43
|
+
description: 'Without liveness probes, deadlocked or crashed applications continue running without recovery.',
|
|
44
|
+
exploitExample: 'Application deadlocks → No liveness probe to detect → Container stays running but unresponsive → Service degradation',
|
|
45
|
+
realWorldImpact: [
|
|
46
|
+
'Undetected application failures',
|
|
47
|
+
'No automatic recovery from deadlocks',
|
|
48
|
+
'Extended service outages',
|
|
49
|
+
'Manual intervention required for restarts',
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
remediation: {
|
|
53
|
+
before: `containers:\n - name: app\n image: myapp:1.0`,
|
|
54
|
+
after: `containers:\n - name: app\n image: myapp:1.0\n livenessProbe:\n httpGet:\n path: /healthz\n port: 8080\n initialDelaySeconds: 30\n periodSeconds: 10\n timeoutSeconds: 5\n failureThreshold: 3`,
|
|
55
|
+
explanation: 'Configure liveness probe to check if the application is running. Kubernetes will restart the container if probe fails.',
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Check #25: Missing Readiness Probes (Medium - CVSS 5.0)
|
|
63
|
+
* Detects containers without readiness probes
|
|
64
|
+
*/
|
|
65
|
+
function checkMissingReadinessProbe(resource) {
|
|
66
|
+
const podSpec = (0, parser_1.getPodSpec)(resource);
|
|
67
|
+
if (!podSpec)
|
|
68
|
+
return null;
|
|
69
|
+
const containers = podSpec.containers || [];
|
|
70
|
+
const missingProbes = [];
|
|
71
|
+
for (const container of containers) {
|
|
72
|
+
if (!container.readinessProbe) {
|
|
73
|
+
missingProbes.push(container.name);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (missingProbes.length > 0) {
|
|
77
|
+
return {
|
|
78
|
+
severity: 'medium',
|
|
79
|
+
message: `Containers without readiness probes in ${(0, parser_1.getResourceIdentifier)(resource)}: ${missingProbes.join(', ')}`,
|
|
80
|
+
suggestion: 'Add readinessProbe to prevent routing traffic to containers that are not ready to serve requests.',
|
|
81
|
+
category: 'kubernetes-missing-readiness-probe',
|
|
82
|
+
cvssScore: 5.0,
|
|
83
|
+
exploitLikelihood: 'medium',
|
|
84
|
+
impact: 'availability',
|
|
85
|
+
owasp: 'A04:2021',
|
|
86
|
+
cwe: 'CWE-400',
|
|
87
|
+
attackVector: {
|
|
88
|
+
description: 'Without readiness probes, Kubernetes routes traffic to containers still initializing, causing request failures.',
|
|
89
|
+
exploitExample: 'New pod starts → No readiness probe → Receives traffic immediately → Application not ready → 500 errors to users',
|
|
90
|
+
realWorldImpact: [
|
|
91
|
+
'Traffic routed to unready pods',
|
|
92
|
+
'Failed requests during startup',
|
|
93
|
+
'Poor user experience during deployments',
|
|
94
|
+
'Connection errors and timeouts',
|
|
95
|
+
],
|
|
96
|
+
},
|
|
97
|
+
remediation: {
|
|
98
|
+
before: `containers:\n - name: app\n image: myapp:1.0`,
|
|
99
|
+
after: `containers:\n - name: app\n image: myapp:1.0\n readinessProbe:\n httpGet:\n path: /ready\n port: 8080\n initialDelaySeconds: 10\n periodSeconds: 5\n timeoutSeconds: 3\n successThreshold: 1\n failureThreshold: 3`,
|
|
100
|
+
explanation: 'Configure readiness probe to check if the application is ready to receive traffic. Pod will not receive traffic until probe succeeds.',
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Run all service security checks on a resource
|
|
108
|
+
*/
|
|
109
|
+
function runServiceSecurityChecks(resource) {
|
|
110
|
+
const vulnerabilities = [];
|
|
111
|
+
const checks = [checkMissingLivenessProbe, checkMissingReadinessProbe];
|
|
112
|
+
for (const check of checks) {
|
|
113
|
+
const vuln = check(resource);
|
|
114
|
+
if (vuln) {
|
|
115
|
+
vulnerabilities.push(vuln);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return vulnerabilities;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=service-security.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-security.js","sourceRoot":"","sources":["../../../../../../../../src/lib/analyzers/kubernetes/checks/service-security.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kubernetes YAML Parser
|
|
3
|
+
*
|
|
4
|
+
* WR3 Week 6: Kubernetes YAML Security Scanner
|
|
5
|
+
* Parses Kubernetes YAML manifests (single and multi-document)
|
|
6
|
+
*
|
|
7
|
+
* Created: February 5, 2026
|
|
8
|
+
*/
|
|
9
|
+
import { KubernetesResource } from './types';
|
|
10
|
+
/**
|
|
11
|
+
* Parse Kubernetes YAML content (supports multi-document YAML with ---)
|
|
12
|
+
*
|
|
13
|
+
* @param yamlContent - YAML string to parse
|
|
14
|
+
* @returns Array of Kubernetes resources
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseKubernetes(yamlContent: string): KubernetesResource[];
|
|
17
|
+
/**
|
|
18
|
+
* Check if an object is a valid Kubernetes resource
|
|
19
|
+
*
|
|
20
|
+
* @param obj - Object to check
|
|
21
|
+
* @returns True if object has apiVersion and kind
|
|
22
|
+
*/
|
|
23
|
+
export declare function isKubernetesResource(obj: any): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Check if YAML content contains Kubernetes resources
|
|
26
|
+
*
|
|
27
|
+
* @param yamlContent - YAML string to check
|
|
28
|
+
* @returns True if content contains K8s resources
|
|
29
|
+
*/
|
|
30
|
+
export declare function isKubernetesYAML(yamlContent: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Extract all containers from a Kubernetes resource
|
|
33
|
+
* Handles Pod, Deployment, StatefulSet, DaemonSet, Job, CronJob
|
|
34
|
+
*
|
|
35
|
+
* @param resource - Kubernetes resource
|
|
36
|
+
* @returns Array of containers (including initContainers)
|
|
37
|
+
*/
|
|
38
|
+
export declare function extractContainers(resource: KubernetesResource): Array<{
|
|
39
|
+
container: any;
|
|
40
|
+
isInitContainer: boolean;
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Get pod spec from various Kubernetes workload resources
|
|
44
|
+
*
|
|
45
|
+
* @param resource - Kubernetes resource
|
|
46
|
+
* @returns Pod spec or null
|
|
47
|
+
*/
|
|
48
|
+
export declare function getPodSpec(resource: KubernetesResource): any | null;
|
|
49
|
+
/**
|
|
50
|
+
* Get resource identifier for error messages
|
|
51
|
+
*
|
|
52
|
+
* @param resource - Kubernetes resource
|
|
53
|
+
* @returns Formatted identifier (e.g., "Deployment/default/nginx")
|
|
54
|
+
*/
|
|
55
|
+
export declare function getResourceIdentifier(resource: KubernetesResource): string;
|
|
56
|
+
/**
|
|
57
|
+
* Check if resource is in a production-like namespace
|
|
58
|
+
*
|
|
59
|
+
* @param resource - Kubernetes resource
|
|
60
|
+
* @returns True if in prod/production/live namespace
|
|
61
|
+
*/
|
|
62
|
+
export declare function isProductionResource(resource: KubernetesResource): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Get all environment variables from a container (including valueFrom)
|
|
65
|
+
*
|
|
66
|
+
* @param container - Container spec
|
|
67
|
+
* @returns Array of environment variable names and values
|
|
68
|
+
*/
|
|
69
|
+
export declare function getContainerEnvVars(container: any): Array<{
|
|
70
|
+
name: string;
|
|
71
|
+
value?: string;
|
|
72
|
+
source?: string;
|
|
73
|
+
}>;
|
|
74
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../../../../../src/lib/analyzers/kubernetes/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE7C;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAwCzE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAWtD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAW7D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,KAAK,CAAC;IACrE,SAAS,EAAE,GAAG,CAAC;IACf,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC,CAmCD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,kBAAkB,GAAG,GAAG,GAAG,IAAI,CAkBnE;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,CAG1E;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAK1E;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,GAAG,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAe5G"}
|