@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildCsp, inspectHeaders } from "../../src/network/http";
|
||||
import { buildCsp, inspectCsp, inspectHeaders } from "../../src/network/http";
|
||||
import { lookupMime } from "../../src/network/mime";
|
||||
|
||||
describe("HTTP helpers", () => {
|
||||
@@ -29,6 +29,83 @@ describe("HTTP helpers", () => {
|
||||
expect(result.policy).toContain("object-src 'none'");
|
||||
expect(result.warnings.join(" ")).toMatch(/unsafe-eval/u);
|
||||
});
|
||||
|
||||
it("analyses deployed CSP, cookies, HSTS and framing defenses", () => {
|
||||
const result = inspectHeaders(
|
||||
"Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-eval'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'\n" +
|
||||
"Strict-Transport-Security: max-age=60\n" +
|
||||
"Set-Cookie: session=abc; SameSite=None\n" +
|
||||
"X-Content-Type-Options: nosniff\n" +
|
||||
"Referrer-Policy: strict-origin",
|
||||
);
|
||||
expect(result.securityFindings.map((finding) => finding.code)).toEqual(
|
||||
expect.arrayContaining([
|
||||
"csp-unsafe-eval",
|
||||
"hsts-short",
|
||||
"cookie-secure",
|
||||
"cookie-http-only",
|
||||
"cookie-none-insecure",
|
||||
]),
|
||||
);
|
||||
expect(result.csp?.directives).toContainEqual({
|
||||
name: "object-src",
|
||||
values: ["'none'"],
|
||||
});
|
||||
});
|
||||
|
||||
it("identifies duplicate and dangerous CSP directives", () => {
|
||||
const result = inspectCsp(
|
||||
"default-src *; script-src data:; script-src 'self'",
|
||||
);
|
||||
expect(result.findings.map((finding) => finding.code)).toEqual(
|
||||
expect.arrayContaining([
|
||||
"csp-wildcard",
|
||||
"csp-script-data",
|
||||
"csp-duplicate-directive",
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("analyses every enforcing CSP field rather than silently dropping later fields", () => {
|
||||
const result = inspectHeaders(
|
||||
"Content-Security-Policy: default-src 'self'; object-src 'none'\n" +
|
||||
"Content-Security-Policy: script-src 'unsafe-eval'; object-src 'none'",
|
||||
);
|
||||
expect(result.cspFields).toHaveLength(2);
|
||||
expect(result.securityFindings).toContainEqual(
|
||||
expect.objectContaining({
|
||||
code: "csp-unsafe-eval",
|
||||
message: expect.stringContaining("CSP field 2"),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("uses the first duplicate directive and validates X-Frame-Options", () => {
|
||||
const csp = inspectCsp(
|
||||
"default-src 'self'; object-src *; object-src 'none'",
|
||||
);
|
||||
expect(csp.findings.map((finding) => finding.code)).toContain(
|
||||
"csp-object-src-open",
|
||||
);
|
||||
const headers = inspectHeaders(
|
||||
"X-Frame-Options: ALLOW-FROM https://example.test",
|
||||
);
|
||||
expect(headers.securityFindings.map((finding) => finding.code)).toContain(
|
||||
"x-frame-options-invalid",
|
||||
);
|
||||
});
|
||||
|
||||
it("does not apply sources from ignored duplicate CSP directives", () => {
|
||||
const csp = inspectCsp(
|
||||
"default-src 'self'; script-src 'self'; script-src 'unsafe-eval' data:",
|
||||
);
|
||||
expect(csp.findings.map((finding) => finding.code)).not.toContain(
|
||||
"csp-unsafe-eval",
|
||||
);
|
||||
expect(csp.findings.map((finding) => finding.code)).toContain(
|
||||
"csp-duplicate-directive",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("MIME lookup", () => {
|
||||
|
||||
Reference in New Issue
Block a user