mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 13:01:56 +00:00
98 lines
3.0 KiB
TypeScript
98 lines
3.0 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { validateYaml } from "./yaml";
|
|
|
|
// The Scan Configuration editor (like the Mutelist editor) validates only YAML
|
|
// *syntax* on the client; the API validates the configuration values
|
|
// (ranges/enums) on create/update. These cover the syntax check the editor and
|
|
// `scanConfigurationFormSchema` rely on.
|
|
describe("validateYaml", () => {
|
|
it("accepts a mapping with provider sections", () => {
|
|
// When
|
|
const result = validateYaml("aws:\n max_unused_access_keys_days: 45");
|
|
|
|
// Then
|
|
expect(result.isValid).toBe(true);
|
|
});
|
|
|
|
it("accepts a key with no value yet (the `aws:` typing state)", () => {
|
|
// When — `aws:` parses to { aws: null }, still a mapping
|
|
const result = validateYaml("aws:");
|
|
|
|
// Then
|
|
expect(result.isValid).toBe(true);
|
|
});
|
|
|
|
it("rejects malformed YAML with a syntax error", () => {
|
|
// When — unmatched bracket is invalid flow syntax
|
|
const result = validateYaml("aws: [1, 2");
|
|
|
|
// Then
|
|
expect(result.isValid).toBe(false);
|
|
expect(result.error).toBeTruthy();
|
|
});
|
|
|
|
it("rejects a top-level list (config must be a mapping)", () => {
|
|
// When
|
|
const result = validateYaml("- aws\n- azure");
|
|
|
|
// Then
|
|
expect(result.isValid).toBe(false);
|
|
});
|
|
|
|
it("rejects empty content", () => {
|
|
// When
|
|
const result = validateYaml("");
|
|
|
|
// Then
|
|
expect(result.isValid).toBe(false);
|
|
});
|
|
|
|
it("rejects a scalar (not a mapping)", () => {
|
|
// When — a bare word parses to the string "aws", not a mapping
|
|
const result = validateYaml("aws");
|
|
|
|
// Then
|
|
expect(result.isValid).toBe(false);
|
|
});
|
|
|
|
// Users author these documents by hand in the Mutelist and Scan Configuration
|
|
// editors, so anchors, aliases and merge keys are legitimate input the syntax
|
|
// check must keep accepting across js-yaml upgrades (4.3.0 rewrote merge-key
|
|
// handling for CVE-2026-59869).
|
|
it("accepts anchors, aliases and merge keys", () => {
|
|
// When
|
|
const result = validateYaml(
|
|
[
|
|
"defaults: &defaults",
|
|
" max_unused_access_keys_days: 45",
|
|
"aws:",
|
|
" <<: *defaults",
|
|
" max_console_access_days: 45",
|
|
].join("\n"),
|
|
);
|
|
|
|
// Then
|
|
expect(result.isValid).toBe(true);
|
|
});
|
|
|
|
it("rejects a merge-key amplification document (CVE-2026-59869 shape)", () => {
|
|
// Given — each mapping merges the previous one and adds a distinct key, so
|
|
// merged-key copies grow quadratically (~45k total here). js-yaml 4.3.0
|
|
// fixes the CVE by capping that work (maxTotalMergeKeys) and rejecting the
|
|
// document; a vulnerable parser accepts it instead, turning the assertion
|
|
// below red without relying on timing or suite timeouts.
|
|
const chain = ["a0: &a0 { k0: 0 }"];
|
|
for (let i = 1; i < 300; i++) {
|
|
chain.push(`a${i}: &a${i} { <<: *a${i - 1}, k${i}: ${i} }`);
|
|
}
|
|
|
|
// When
|
|
const result = validateYaml(chain.join("\n"));
|
|
|
|
// Then
|
|
expect(result.isValid).toBe(false);
|
|
expect(result.error).toMatch(/merge keys/i);
|
|
});
|
|
});
|