mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-09 21:14:22 +00:00
fix(kubernetes): reject exec auth in cloud kubeconfigs (#11753)
This commit is contained in:
@@ -150,3 +150,73 @@ describe("addCredentialsFormSchema - okta", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("addCredentialsFormSchema - kubernetes", () => {
|
||||
const BASE_KUBERNETES_VALUES = {
|
||||
[ProviderCredentialFields.PROVIDER_ID]: "provider-kubernetes-1",
|
||||
[ProviderCredentialFields.PROVIDER_TYPE]: "kubernetes",
|
||||
} as const;
|
||||
|
||||
it("accepts kubeconfig content without exec authentication", () => {
|
||||
const schema = addCredentialsFormSchema("kubernetes");
|
||||
|
||||
const result = schema.safeParse({
|
||||
...BASE_KUBERNETES_VALUES,
|
||||
[ProviderCredentialFields.KUBECONFIG_CONTENT]: `apiVersion: v1
|
||||
kind: Config
|
||||
users:
|
||||
- name: test-user
|
||||
user:
|
||||
token: test-token`,
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
it("reports kubeconfig exec authentication on kubeconfig_content field", () => {
|
||||
const schema = addCredentialsFormSchema("kubernetes");
|
||||
|
||||
const result = schema.safeParse({
|
||||
...BASE_KUBERNETES_VALUES,
|
||||
[ProviderCredentialFields.KUBECONFIG_CONTENT]: `apiVersion: v1
|
||||
kind: Config
|
||||
users:
|
||||
- name: test-user
|
||||
user:
|
||||
exec:
|
||||
apiVersion: client.authentication.k8s.io/v1
|
||||
command: kubectl`,
|
||||
});
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
if (result.success) return;
|
||||
|
||||
expect(result.error.issues).toContainEqual(
|
||||
expect.objectContaining({
|
||||
path: [ProviderCredentialFields.KUBECONFIG_CONTENT],
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("accepts malformed kubeconfig content for backend validation", () => {
|
||||
const schema = addCredentialsFormSchema("kubernetes");
|
||||
|
||||
const result = schema.safeParse({
|
||||
...BASE_KUBERNETES_VALUES,
|
||||
[ProviderCredentialFields.KUBECONFIG_CONTENT]: "apiVersion: [",
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
it("accepts non-mapping kubeconfig content for backend validation", () => {
|
||||
const schema = addCredentialsFormSchema("kubernetes");
|
||||
|
||||
const result = schema.safeParse({
|
||||
...BASE_KUBERNETES_VALUES,
|
||||
[ProviderCredentialFields.KUBECONFIG_CONTENT]: "[]",
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
+37
-1
@@ -1,3 +1,4 @@
|
||||
import yaml from "js-yaml";
|
||||
import { z } from "zod";
|
||||
|
||||
import { ProviderCredentialFields } from "@/lib/provider-credentials/provider-credential-fields";
|
||||
@@ -5,6 +6,35 @@ import { validateMutelistYaml, validateYaml } from "@/lib/yaml";
|
||||
|
||||
import { PROVIDER_TYPES, ProviderType } from "./providers";
|
||||
|
||||
export const KUBECONFIG_EXEC_AUTHENTICATION_ERROR =
|
||||
"Kubernetes kubeconfig exec authentication is not supported in Prowler Cloud for security reasons.";
|
||||
|
||||
const isRecord = (value: unknown): value is Record<string, unknown> => {
|
||||
return typeof value === "object" && value !== null && !Array.isArray(value);
|
||||
};
|
||||
|
||||
export const kubeconfigContainsExecAuthentication = (
|
||||
value: string,
|
||||
): boolean => {
|
||||
try {
|
||||
const parsed = yaml.load(value);
|
||||
|
||||
if (!isRecord(parsed) || !Array.isArray(parsed.users)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parsed.users.some((userEntry) => {
|
||||
if (!isRecord(userEntry) || !isRecord(userEntry.user)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return "exec" in userEntry.user;
|
||||
});
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
export const addRoleFormSchema = z.object({
|
||||
name: z.string().min(1, "Name is required"),
|
||||
manage_users: z.boolean().default(false),
|
||||
@@ -207,7 +237,13 @@ export const addCredentialsFormSchema = (
|
||||
? {
|
||||
[ProviderCredentialFields.KUBECONFIG_CONTENT]: z
|
||||
.string()
|
||||
.min(1, "Kubeconfig Content is required"),
|
||||
.min(1, "Kubeconfig Content is required")
|
||||
.refine(
|
||||
(value) => !kubeconfigContainsExecAuthentication(value),
|
||||
{
|
||||
error: KUBECONFIG_EXEC_AUTHENTICATION_ERROR,
|
||||
},
|
||||
),
|
||||
}
|
||||
: providerType === "m365"
|
||||
? {
|
||||
|
||||
Reference in New Issue
Block a user