Prefer innerText instead of innerHTML

The previous implementation can lead to XSS injection
This commit is contained in:
Chocobozzz 2024-04-04 13:24:41 +02:00
parent 01e4fd067e
commit a93217d2da
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
14 changed files with 27 additions and 44 deletions

View File

@ -62,8 +62,8 @@ export class ConfirmComponent implements OnInit {
this.confirmButtonText = confirmButtonText || $localize`Confirm`
this.html.toSafeHtml(message)
.then(message => {
this.message = message
.then(html => {
this.message = html
this.showModal()
})

View File

@ -29,7 +29,7 @@ class PeerTubeLinkButton extends Component {
createEl () {
const el = videojs.dom.createEl('a', {
href: this.buildLink(),
innerHTML: this.options_.instanceName,
innerText: this.options_.instanceName,
title: this.player().localize('Video page (new window)'),
className: 'vjs-peertube-link',
target: '_blank'

View File

@ -37,7 +37,7 @@ class PeerTubeDockComponent extends Component {
const title = videojs.dom.createEl('div', {
className: 'peertube-dock-title',
title: this.options_.title,
innerHTML: this.options_.title
innerText: this.options_.title
})
elWrapperTitleDescription.appendChild(title)
@ -47,7 +47,7 @@ class PeerTubeDockComponent extends Component {
const description = videojs.dom.createEl('div', {
className: 'peertube-dock-description',
title: this.options_.description,
innerHTML: this.options_.description
innerText: this.options_.description
})
elWrapperTitleDescription.appendChild(description)

View File

@ -22,19 +22,16 @@ class PlaylistButton extends ClickableComponent {
createEl () {
this.wrapper = super.createEl('div', {
className: 'vjs-playlist-button',
innerHTML: '',
tabIndex: -1
}) as HTMLElement
const icon = super.createEl('div', {
className: 'vjs-playlist-icon',
innerHTML: '',
tabIndex: -1
})
this.playlistInfoElement = super.createEl('div', {
className: 'vjs-playlist-info',
innerHTML: '',
tabIndex: -1
}) as HTMLElement
@ -47,7 +44,7 @@ class PlaylistButton extends ClickableComponent {
}
update () {
this.playlistInfoElement.innerHTML = this.options_.getCurrentPosition() + '/' + this.options_.playlist.videosLength
this.playlistInfoElement.innerText = this.options_.getCurrentPosition() + '/' + this.options_.playlist.videosLength
this.wrapper.title = this.player().localize('Playlist: {1}', [ this.options_.playlist.displayName ])
}

View File

@ -36,8 +36,7 @@ class PlaylistMenuItem extends Component {
createEl () {
const li = super.createEl('li', {
className: 'vjs-playlist-menu-item',
innerHTML: ''
className: 'vjs-playlist-menu-item'
}) as HTMLElement
if (!this.options_.element.video) {
@ -50,7 +49,7 @@ class PlaylistMenuItem extends Component {
const position = super.createEl('div', {
className: 'item-position',
innerHTML: this.options_.element.position
innerText: this.options_.element.position
})
positionBlock.appendChild(position)
@ -92,12 +91,12 @@ class PlaylistMenuItem extends Component {
})
const title = super.createEl('div', {
innerHTML: videoElement.video.name,
innerText: videoElement.video.name,
className: 'title'
})
const channel = super.createEl('div', {
innerHTML: videoElement.video.channel.displayName,
innerText: videoElement.video.channel.displayName,
className: 'channel'
})
@ -111,7 +110,7 @@ class PlaylistMenuItem extends Component {
if (videoElement.stopTimestamp) html += ' - ' + secondsToTime(videoElement.stopTimestamp)
const timestamps = super.createEl('div', {
innerHTML: html,
innerText: html,
className: 'timestamps'
})
@ -125,7 +124,7 @@ class PlaylistMenuItem extends Component {
private buildUnavailableVideo (li: HTMLElement) {
const block = super.createEl('div', {
className: 'item-unavailable',
innerHTML: this.player().localize('Unavailable video')
innerTExt: this.player().localize('Unavailable video')
})
li.appendChild(block)

View File

@ -73,7 +73,6 @@ class PlaylistMenu extends Component {
const menu = super.createEl('div', {
className: 'vjs-playlist-menu',
innerHTML: '',
tabIndex: -1
})
@ -84,13 +83,13 @@ class PlaylistMenu extends Component {
const headerLeft = super.createEl('div')
const leftTitle = super.createEl('div', {
innerHTML: this.options_.playlist.displayName,
innerText: this.options_.playlist.displayName,
className: 'title'
})
const playlistChannel = this.options_.playlist.videoChannel
const leftSubtitle = super.createEl('div', {
innerHTML: playlistChannel
innerText: playlistChannel
? this.player().localize('By {1}', [ playlistChannel.displayName ])
: '',
className: 'channel'

View File

@ -20,7 +20,6 @@ class SettingsDialog extends Component {
return super.createEl('div', {
className: 'vjs-settings-dialog vjs-modal-overlay',
innerHTML: '',
tabIndex: -1
}, {
'role': 'dialog',

View File

@ -7,7 +7,6 @@ class SettingsPanelChild extends Component {
createEl () {
return super.createEl('div', {
className: 'vjs-settings-panel-child',
innerHTML: '',
tabIndex: -1
})
}

View File

@ -7,7 +7,6 @@ class SettingsPanel extends Component {
createEl () {
return super.createEl('div', {
className: 'vjs-settings-panel',
innerHTML: '',
tabIndex: -1
})
}

View File

@ -285,15 +285,15 @@ class StatsCard extends Component {
if (player.muted()) volume += player.localize(' (muted)')
const networkActivity = playerNetworkInfo.downloadSpeed
? `${playerNetworkInfo.downloadSpeed} ⇓ / ${playerNetworkInfo.uploadSpeed} ⇑`
? `${playerNetworkInfo.downloadSpeed} \u21D3 / ${playerNetworkInfo.uploadSpeed} \u21D1`
: undefined
let totalTransferred = playerNetworkInfo.totalDownloaded
? `${playerNetworkInfo.totalDownloaded} ⇓`
? `${playerNetworkInfo.totalDownloaded} \u21D3`
: ''
if (playerNetworkInfo.totalUploaded) {
totalTransferred += `/ ${playerNetworkInfo.totalUploaded} ⇑`
totalTransferred += `/ ${playerNetworkInfo.totalUploaded} \u21D1`
}
const downloadBreakdown = playerNetworkInfo.downloadedFromServer
@ -337,16 +337,16 @@ class StatsCard extends Component {
el.root.style.display = 'block'
if (el.value.innerHTML === value) return
el.value.innerHTML = value
if (el.value.innerText === value) return
el.value.innerText = value
}
private buildInfoRow (labelText: string, valueHTML?: string) {
private buildInfoRow (labelText: string) {
const root = videojs.dom.createEl('div') as HTMLElement
root.style.display = 'none'
const label = videojs.dom.createEl('div', { innerText: labelText }) as HTMLElement
const value = videojs.dom.createEl('span', { innerHTML: valueHTML }) as HTMLElement
const value = videojs.dom.createEl('span') as HTMLElement
root.appendChild(label)
root.appendChild(value)

View File

@ -121,7 +121,7 @@ export class EndCard extends Component {
this.autoplayRing.setAttribute('stroke-dasharray', `${this.dashOffsetStart}`)
this.autoplayRing.setAttribute('stroke-dashoffset', `${-this.dashOffsetStart}`)
this.title.innerHTML = this.options_.getTitle()
this.title.innerText = this.options_.getTitle()
if (this.totalTicks === 0) {
return cb(false)

View File

@ -60,15 +60,6 @@
.peertube-dock-description {
font-size: 11px;
line-height: 1.5;
.text::before {
@include margin-right(4px);
}
.text::after {
@include margin-left(4px);
transform: scale(-1, 1);
}
}
@media screen and (max-width: $screen-width-750) {

View File

@ -69,14 +69,14 @@ export class PlayerHTML {
videoPasswordBlock.style.display = 'flex'
const videoPasswordTitle = document.getElementById('video-password-title')
videoPasswordTitle.innerHTML = translatedTitle
videoPasswordTitle.innerText = translatedTitle
const videoPasswordMessage = document.getElementById('video-password-content')
videoPasswordMessage.innerHTML = translatedMessage
videoPasswordMessage.innerText = translatedMessage
if (incorrectPassword) {
const videoPasswordError = document.getElementById('video-password-error')
videoPasswordError.innerHTML = peertubeTranslate('Incorrect password, please enter a correct password', translations)
videoPasswordError.innerText = peertubeTranslate('Incorrect password, please enter a correct password', translations)
videoPasswordError.style.transform = 'scale(1.2)'
setTimeout(() => {
@ -85,7 +85,7 @@ export class PlayerHTML {
}
const videoPasswordSubmitButton = document.getElementById('video-password-submit')
videoPasswordSubmitButton.innerHTML = peertubeTranslate('Watch Video', translations)
videoPasswordSubmitButton.innerText = peertubeTranslate('Watch Video', translations)
const videoPasswordInput = document.getElementById('video-password-input') as HTMLInputElement
videoPasswordInput.placeholder = peertubeTranslate('Password', translations)

View File

@ -436,7 +436,7 @@ export class PlayerOptionsBuilder {
: undefined
const description = this.hasWarningTitle() && this.hasP2PEnabled()
? '<span class="text">' + peertubeTranslate('Watching this video may reveal your IP address to others.') + '</span>'
? peertubeTranslate('Watching this video may reveal your IP address to others.')
: undefined
if (!title && !description) return