diff --git a/src/node/routes/errors.ts b/src/node/routes/errors.ts index 757e9f74..66f424ac 100644 --- a/src/node/routes/errors.ts +++ b/src/node/routes/errors.ts @@ -6,7 +6,7 @@ import { WebsocketRequest } from "../../../typings/pluginapi" import { HttpCode } from "../../common/http" import { rootPath } from "../constants" import { replaceTemplates } from "../http" -import { getMediaMime } from "../util" +import { escapeHtml, getMediaMime } from "../util" const notFoundCodes = ["ENOENT", "EISDIR", "FileNotFound"] export const errorHandler: express.ErrorRequestHandler = async (err, req, res, next) => { @@ -29,7 +29,7 @@ export const errorHandler: express.ErrorRequestHandler = async (err, req, res, n replaceTemplates(req, content) .replace(/{{ERROR_TITLE}}/g, status) .replace(/{{ERROR_HEADER}}/g, status) - .replace(/{{ERROR_BODY}}/g, err.message), + .replace(/{{ERROR_BODY}}/g, escapeHtml(err.message)), ) } else { res.json({ diff --git a/test/unit/node/routes/errors.test.ts b/test/unit/node/routes/errors.test.ts new file mode 100644 index 00000000..ffa8f479 --- /dev/null +++ b/test/unit/node/routes/errors.test.ts @@ -0,0 +1,35 @@ +import express from "express" +import { errorHandler } from "../../../../src/node/routes/errors" + +describe("error page is rendered for text/html requests", () => { + it("escapes any html in the error messages", async () => { + const next = jest.fn() + const err = { + code: "ENOENT", + statusCode: 404, + message: ";>hello", + } + const req = createRequest() + const res = { + status: jest.fn().mockReturnValue(this), + send: jest.fn().mockReturnValue(this), + set: jest.fn().mockReturnValue(this), + } as unknown as express.Response + + await errorHandler(err, req, res, next) + expect(res.status).toHaveBeenCalledWith(404) + expect(res.send).toHaveBeenCalledWith(expect.not.stringContaining("