From 041609013666c89d19dfae4bc1ea36ee2f3d3c69 Mon Sep 17 00:00:00 2001 From: tsv2013 Date: Fri, 12 Jul 2024 09:53:17 +0300 Subject: [PATCH] Fixed #8549 - Navigate to URL cross-site scripting attack (#8550) Co-authored-by: tsv2013 --- src/utils/utils.ts | 2 +- tests/surveytests.ts | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 9d3877f671..c2e0cfd720 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -157,7 +157,7 @@ function scrollElementByChildId(id: string) { function navigateToUrl(url: string): void { const location = DomWindowHelper.getLocation(); if (!url || !location) return; - location.href = url; + location.href = encodeURIComponent(url); } function wrapUrlForBackgroundImage(url: string): string { diff --git a/tests/surveytests.ts b/tests/surveytests.ts index ffd91568f5..ea5b0e4776 100644 --- a/tests/surveytests.ts +++ b/tests/surveytests.ts @@ -65,6 +65,7 @@ import { defaultV2Css } from "../src/defaultCss/defaultV2Css"; import { StylesManager } from "../src/stylesmanager"; import { ITheme } from "../src/themes"; import { Cover } from "../src/header"; +import { DomWindowHelper } from "../src/global_variables_utils"; export default QUnit.module("Survey"); @@ -20125,3 +20126,21 @@ QUnit.test("Delete panel with questions", (assert) => { assert.notOk(survey.getPanelByName("panel1"), "#5"); assert.notOk(survey.getQuestionByName("question1"), "#6"); }); + +QUnit.test("survey navigateToUrl encode url", function (assert) { + var survey = new SurveyModel({ + questions: [ + { + type: "text", + name: "q1", + } + ], + "navigateToUrl": "javascript:alert(2)", + }); + + const location: Location = {} as any; + DomWindowHelper.getLocation = (() => location); + + survey.doComplete(); + assert.equal(location.href, "javascript%3Aalert(2)", "encoded URL"); +}); \ No newline at end of file