From 1af8e37e9bf2c1629866cd166d6f2cc80760226b Mon Sep 17 00:00:00 2001 From: "potsda.mn-Kollektiv" Date: Thu, 7 Dec 2023 14:28:59 +0100 Subject: [PATCH] fix(front-end): add more security fixes for formatted lists and notifier - introduce html escape function - escape message content in notifier plugin - escape user name in ConversationListItem - escape user name in the Event EditView contacts section - display user summary as plain text in ActorCard Signed-off-by: Thomas Citharel --- src/components/Account/ActorCard.vue | 11 ++++++++++- src/components/Conversations/ConversationListItem.vue | 3 ++- src/plugins/notifier.ts | 3 ++- src/utils/html.ts | 10 ++++++++++ src/views/Event/EditView.vue | 3 ++- 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/components/Account/ActorCard.vue b/src/components/Account/ActorCard.vue index 2124b746d..6856a2bd0 100644 --- a/src/components/Account/ActorCard.vue +++ b/src/components/Account/ActorCard.vue @@ -30,7 +30,7 @@ @{{ usernameWithDomain(actor) }}

+
{ const formattedListOfParticipants = computed(() => { return formatList( otherParticipants.value.map( - (participant) => `${displayName(participant)}` + (participant) => `${escapeHtml(displayName(participant))}` ) ); }); diff --git a/src/plugins/notifier.ts b/src/plugins/notifier.ts index 0b5e9c3fe..23719b706 100644 --- a/src/plugins/notifier.ts +++ b/src/plugins/notifier.ts @@ -1,3 +1,4 @@ +import { escapeHtml } from "@/utils/html"; import { App } from "vue"; export class Notifier { @@ -21,7 +22,7 @@ export class Notifier { private notification(message: string, type: string) { this.app.config.globalProperties.$oruga.notification.open({ - message, + message: escapeHtml(message), duration: 5000, position: "bottom-right", type, diff --git a/src/utils/html.ts b/src/utils/html.ts index 02b8763b4..7f0ac34a9 100644 --- a/src/utils/html.ts +++ b/src/utils/html.ts @@ -5,3 +5,13 @@ export const getValueFromMeta = (name: string): string | null => { } return null; }; + +export function escapeHtml(html: string) { + const p = document.createElement("p"); + p.appendChild(document.createTextNode(html.trim())); + + const escapedContent = p.innerHTML; + p.remove(); + + return escapedContent; +} diff --git a/src/views/Event/EditView.vue b/src/views/Event/EditView.vue index d833d8dea..3d9deba6c 100644 --- a/src/views/Event/EditView.vue +++ b/src/views/Event/EditView.vue @@ -180,7 +180,7 @@ { contact: formatList( event.contacts.map((contact) => - displayNameAndUsername(contact) + escapeHtml(displayNameAndUsername(contact)) ) ), }, @@ -628,6 +628,7 @@ import { useHead } from "@unhead/vue"; import { useProgrammatic } from "@oruga-ui/oruga-next"; import type { Locale } from "date-fns"; import sortBy from "lodash/sortBy"; +import { escapeHtml } from "@/utils/html"; const DEFAULT_LIMIT_NUMBER_OF_PLACES = 10;