Export.csv.test.ts

1007 B · raw

1// @vitest-environment jsdom2import { describe, expect, it } from "vitest";34import { csvSafe } from "./Export";56describe("csvSafe — CSV/spreadsheet formula-injection neutralization (audit MEDIUM)", () => {7  it("prefixes formula-trigger leading characters with a quote", () => {8    for (const lead of ["=", "+", "-", "@", ";", "\t", "\r"]) {9      expect(csvSafe(lead + "HYPERLINK(\"http://evil\")")).toBe("'" + lead + "HYPERLINK(\"http://evil\")");10    }11  });1213  it("neutralizes the classic DDE / exfiltration payloads", () => {14    expect(csvSafe('=cmd|\'/c calc\'!A1')).toBe("'=cmd|'/c calc'!A1");15    expect(csvSafe('@SUM(A1:A9)')).toBe("'@SUM(A1:A9)");16  });1718  it("leaves ordinary values untouched", () => {19    expect(csvSafe("[email protected]")).toBe("[email protected]"); // @ not leading20    expect(csvSafe("https://github.com")).toBe("https://github.com");21    expect(csvSafe("correct horse battery staple")).toBe("correct horse battery staple");22    expect(csvSafe("")).toBe("");23  });24});