Escape quotes for html attributes

pull/6126/head
Chocobozzz 2023-12-14 11:32:43 +01:00
parent 63c4a02ce0
commit edc695263f
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
3 changed files with 26 additions and 6 deletions

View File

@ -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, '\\"')
}

View File

@ -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: '<strong>"super description"</strong>' })
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(`<meta property="twitter:description" content="\\"super description\\"" />`)
expect(text).to.contain(`<meta property="og:description" content="\\"super description\\"" />`)
})
})
after(async function () {
await cleanupTests(servers)
})

View File

@ -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 = `<meta name="description" content="${content}" />`
const descriptionTag = `<meta name="description" content="${escapeAttribute(content)}" />`
return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.DESCRIPTION, descriptionTag)
}
@ -93,7 +93,7 @@ export class TagsHtml {
const tagValue = openGraphMetaTags[tagName]
if (!tagValue) return
tagsStr += `<meta property="${tagName}" content="${tagValue}" />`
tagsStr += `<meta property="${tagName}" content="${escapeAttribute(tagValue)}" />`
})
// Standard
@ -101,7 +101,7 @@ export class TagsHtml {
const tagValue = standardMetaTags[tagName]
if (!tagValue) return
tagsStr += `<meta property="${tagName}" content="${tagValue}" />`
tagsStr += `<meta property="${tagName}" content="${escapeAttribute(tagValue)}" />`
})
// Twitter card
@ -109,12 +109,13 @@ export class TagsHtml {
const tagValue = twitterCardMetaTags[tagName]
if (!tagValue) return
tagsStr += `<meta property="${tagName}" content="${tagValue}" />`
tagsStr += `<meta property="${tagName}" content="${escapeAttribute(tagValue)}" />`
})
// OEmbed
for (const oembedLinkTag of oembedLinkTags) {
tagsStr += `<link rel="alternate" type="${oembedLinkTag.type}" href="${oembedLinkTag.href}" title="${oembedLinkTag.escapedTitle}" />`
// eslint-disable-next-line max-len
tagsStr += `<link rel="alternate" type="${oembedLinkTag.type}" href="${oembedLinkTag.href}" title="${escapeAttribute(oembedLinkTag.escapedTitle)}" />`
}
// Schema.org