From c0e123a8012c8fd0aa0bbce3edbcf1e25f63eea4 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 30 Jun 2021 10:39:48 -0700 Subject: [PATCH] fix(http): escape req.query.to in replaceTemplates --- src/node/http.ts | 4 ++-- src/node/routes/login.ts | 4 ++-- test/unit/routes/login.test.ts | 9 ++++++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/node/http.ts b/src/node/http.ts index 76eb52073..d7ffa1f14 100644 --- a/src/node/http.ts +++ b/src/node/http.ts @@ -7,7 +7,7 @@ import { normalize, Options } from "../common/util" import { AuthType, DefaultedArgs } from "./cli" import { commit, rootPath } from "./constants" import { Heart } from "./heart" -import { getPasswordMethod, IsCookieValidArgs, isCookieValid, sanitizeString } from "./util" +import { getPasswordMethod, IsCookieValidArgs, isCookieValid, sanitizeString, escapeHtml } from "./util" declare global { // eslint-disable-next-line @typescript-eslint/no-namespace @@ -35,7 +35,7 @@ export const replaceTemplates = ( ...extraOpts, } return content - .replace(/{{TO}}/g, (typeof req.query.to === "string" && req.query.to) || "/") + .replace(/{{TO}}/g, (typeof req.query.to === "string" && escapeHtml(req.query.to)) || "/") .replace(/{{BASE}}/g, options.base) .replace(/{{CS_STATIC_BASE}}/g, options.csStaticBase) .replace(/"{{OPTIONS}}"/, `'${JSON.stringify(options)}'`) diff --git a/src/node/routes/login.ts b/src/node/routes/login.ts index 63991165c..999b8dfaf 100644 --- a/src/node/routes/login.ts +++ b/src/node/routes/login.ts @@ -112,7 +112,7 @@ router.post("/", async (req, res) => { throw new Error("Incorrect password") } catch (error) { - const htmlToRender = await getRoot(req, error) - res.send(htmlToRender) + const renderedHtml = await getRoot(req, error) + res.send(renderedHtml) } }) diff --git a/test/unit/routes/login.test.ts b/test/unit/routes/login.test.ts index c6e131bdc..ba4fcac8b 100644 --- a/test/unit/routes/login.test.ts +++ b/test/unit/routes/login.test.ts @@ -1,8 +1,7 @@ +import { RateLimiter } from "../../../src/node/routes/login" import * as httpserver from "../../utils/httpserver" import * as integration from "../../utils/integration" -import { RateLimiter } from "../../../src/node/routes/login" - describe("login", () => { describe("RateLimiter", () => { it("should allow one try ", () => { @@ -56,8 +55,12 @@ describe("login", () => { _codeServer = await integration.setup(["--auth=password"], "") }) - afterEach(() => { + afterEach(async () => { process.env.PASSWORD = previousEnvPassword + if (_codeServer) { + await _codeServer.close() + _codeServer = undefined + } }) it("should return HTML with 'Missing password' message", async () => {