From edc695263f5a33ee012d50fa914ee10a385c9433 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 14 Dec 2023 11:32:43 +0100 Subject: [PATCH] Escape quotes for html attributes --- packages/core-utils/src/renderer/html.ts | 6 ++++++ packages/tests/src/client/og-twitter-tags.ts | 13 +++++++++++++ server/core/lib/html/shared/tags-html.ts | 13 +++++++------ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/packages/core-utils/src/renderer/html.ts b/packages/core-utils/src/renderer/html.ts index 365bf7612c3..fb4f19ac029 100644 --- a/packages/core-utils/src/renderer/html.ts +++ b/packages/core-utils/src/renderer/html.ts @@ -69,3 +69,9 @@ export function escapeHTML (stringParam: string) { return String(stringParam).replace(/[&<>"'`=/]/g, s => entityMap[s]) } + +export function escapeAttribute (value: string) { + if (!value) return '' + + return String(value).replace(/"/g, '\\"') +} diff --git a/packages/tests/src/client/og-twitter-tags.ts b/packages/tests/src/client/og-twitter-tags.ts index cdd4a15c71f..e8ddc7c9b8b 100644 --- a/packages/tests/src/client/og-twitter-tags.ts +++ b/packages/tests/src/client/og-twitter-tags.ts @@ -265,6 +265,19 @@ describe('Test Open Graph and Twitter cards HTML tags', function () { }) }) + describe('Escaping', function () { + + it('Should correctly escape values', async function () { + await servers[0].users.updateMe({ description: '"super description"' }) + + const res = await makeGetRequest({ url: servers[0].url, path: '/a/root', accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 }) + const text = res.text + + expect(text).to.contain(``) + expect(text).to.contain(``) + }) + }) + after(async function () { await cleanupTests(servers) }) diff --git a/server/core/lib/html/shared/tags-html.ts b/server/core/lib/html/shared/tags-html.ts index 3df840fd9ab..97f337d4840 100644 --- a/server/core/lib/html/shared/tags-html.ts +++ b/server/core/lib/html/shared/tags-html.ts @@ -1,4 +1,4 @@ -import { escapeHTML } from '@peertube/peertube-core-utils' +import { escapeAttribute, escapeHTML } from '@peertube/peertube-core-utils' import { CONFIG } from '../../../initializers/config.js' import { CUSTOM_HTML_TAG_COMMENTS, EMBED_SIZE, WEBSERVER } from '../../../initializers/constants.js' import { MVideo, MVideoPlaylist } from '../../../types/models/index.js' @@ -61,7 +61,7 @@ export class TagsHtml { static addDescriptionTag (htmlStringPage: string, escapedTruncatedDescription?: string) { const content = escapedTruncatedDescription || escapeHTML(CONFIG.INSTANCE.SHORT_DESCRIPTION) - const descriptionTag = `` + const descriptionTag = `` return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.DESCRIPTION, descriptionTag) } @@ -93,7 +93,7 @@ export class TagsHtml { const tagValue = openGraphMetaTags[tagName] if (!tagValue) return - tagsStr += `` + tagsStr += `` }) // Standard @@ -101,7 +101,7 @@ export class TagsHtml { const tagValue = standardMetaTags[tagName] if (!tagValue) return - tagsStr += `` + tagsStr += `` }) // Twitter card @@ -109,12 +109,13 @@ export class TagsHtml { const tagValue = twitterCardMetaTags[tagName] if (!tagValue) return - tagsStr += `` + tagsStr += `` }) // OEmbed for (const oembedLinkTag of oembedLinkTags) { - tagsStr += `` + // eslint-disable-next-line max-len + tagsStr += `` } // Schema.org