File size: 2,559 Bytes
755a930 d15d7f7 755a930 7843436 755a930 7843436 755a930 7843436 755a930 7843436 755a930 7843436 755a930 7843436 755a930 7843436 755a930 7843436 755a930 7843436 755a930 7843436 755a930 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | /**
* Security Tests (Section 4 of TESTS.md)
*
* Tests XSS escaping in published HTML output.
*/
import { describe, it, expect } from "vitest";
import { renderArticleHTML, type PublishMeta } from "../src/publisher/html-renderer.js";
const EMPTY_CSS = {
variables: ":root { --text-color: #000; }",
reset: "",
base: "",
layout: "",
print: "",
editorTokens: "",
article: "",
components: "",
publisher: "",
};
const BASE_META: PublishMeta = {
title: "Test",
description: "Test description",
authors: [],
affiliations: [],
date: "2025-01-01",
};
const MINIMAL_JSON = {
type: "doc",
content: [{ type: "paragraph", content: [{ type: "text", text: "Hello" }] }],
};
describe("4.4 XSS prevention", () => {
it("4.4.1 licence field is escaped in published HTML", async () => {
const meta: PublishMeta = {
...BASE_META,
licence: '<script>alert("xss")</script>',
};
const html = await renderArticleHTML(MINIMAL_JSON, meta, EMPTY_CSS);
expect(html).not.toContain('<script>alert("xss")</script>');
expect(html).toContain("<script>");
});
it("4.4.2 title is escaped in published HTML", async () => {
const meta: PublishMeta = {
...BASE_META,
title: '<img src=x onerror="alert(1)">',
};
const html = await renderArticleHTML(MINIMAL_JSON, meta, EMPTY_CSS);
expect(html).not.toContain('<img src=x onerror="alert(1)">');
expect(html).toContain("<img");
});
it("4.4.3 description is escaped in meta tags", async () => {
const meta: PublishMeta = {
...BASE_META,
description: '"><script>alert(1)</script>',
};
const html = await renderArticleHTML(MINIMAL_JSON, meta, EMPTY_CSS);
expect(html).not.toContain('"><script>');
expect(html).toContain(""><script>");
});
it("4.4.4 author names are escaped", async () => {
const meta: PublishMeta = {
...BASE_META,
authors: [
{
name: '<script>alert(1)</script>',
affiliationIndices: [],
affiliationNames: [],
},
],
};
const html = await renderArticleHTML(MINIMAL_JSON, meta, EMPTY_CSS);
expect(html).not.toContain('<script>alert(1)</script>');
expect(html).toContain("<script>");
});
it("4.4.5 DOI is escaped in links", async () => {
const meta: PublishMeta = {
...BASE_META,
doi: '"><script>alert(1)</script>',
};
const html = await renderArticleHTML(MINIMAL_JSON, meta, EMPTY_CSS);
expect(html).not.toContain('"><script>');
});
});
|