Skip to content

Commit 4e075d3

Browse files
authored
Merge commit from fork
Data attributes starting with data-mw- cannot be inserted via wikitext. This fixes a stored XSS vulnerability. GHSA-4j5h-mvj3-m48v
1 parent 440fb33 commit 4e075d3

File tree

6 files changed

+15
-15
lines changed

6 files changed

+15
-15
lines changed

includes/EmbedService/EmbedHtmlFormatter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public static function toHtml( AbstractEmbedService $service, array $config = []
101101
->get( 'EmbedVideoRequireConsent' );
102102
if ( $consent === true ) {
103103
$iframeConfig = sprintf(
104-
"data-iframeconfig='%s'",
104+
"data-mw-iframeconfig='%s'",
105105
$service->getIframeConfig( $width, $height )
106106
);
107107
}

includes/EmbedVideo.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ public static function parseEVL( Parser $parser, PPFrame $frame, array $args ):
183183
}
184184

185185
$linkConfig = [
186-
'data-iframeconfig' => $ev->service->getIframeConfig( $ev->args['width'], $ev->args['height'] ),
186+
'data-mw-iframeconfig' => $ev->service->getIframeConfig( $ev->args['width'], $ev->args['height'] ),
187187
'data-service' => $ev->args['service'],
188188
'data-player' => $ev->args['player'] ?? 'default',
189189
'class' => 'embedvideo-evl vplink',

resources/ext.embedVideo.videolink.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const {makeIframe, fetchThumb} = require('./iframe.js');
77
e.preventDefault();
88

99
const player = evl.dataset?.player ?? 'default';
10-
const iframeConfig = JSON.parse(evl.dataset?.iframeconfig ?? '{}');
10+
const iframeConfig = JSON.parse(evl.dataset?.mwIframeconfig ?? '{}');
1111

1212
const playerContainer = document.querySelector(`.embedvideo.evlplayer-${player}`);
1313
const iframe = playerContainer.querySelector('iframe');
@@ -25,7 +25,7 @@ const {makeIframe, fetchThumb} = require('./iframe.js');
2525
// No iframe exists, only when explicit consent is required
2626
const div = document.querySelector(`.embedvideo.evlplayer-${player}`);
2727

28-
if (div === null || evl.dataset?.iframeconfig === null) {
28+
if (div === null || evl.dataset?.mwIframeconfig === null) {
2929
console.warn(`No player with id '${player}' found!.`);
3030
return;
3131
}
@@ -35,7 +35,7 @@ const {makeIframe, fetchThumb} = require('./iframe.js');
3535

3636
const origService = div.dataset?.service;
3737

38-
div.dataset.iframeconfig = evl.dataset.iframeconfig;
38+
div.dataset.mwIframeconfig = evl.dataset.mwIframeconfig;
3939
div.dataset.service = evl.dataset.service;
4040

4141
const serviceMessage = mw.message('embedvideo-service-' + (evl.dataset?.service ?? 'youtube')).escaped();
@@ -46,7 +46,7 @@ const {makeIframe, fetchThumb} = require('./iframe.js');
4646

4747
if (evl.dataset?.privacyUrl !== null) {
4848
const link = document.createElement('a');
49-
link.href = evl.dataset.privacyUrl;
49+
link.href = evl.dataset.privacyUrl;
5050
link.rel = 'nofollow,noopener';
5151
link.target = '_blank';
5252
link.classList.add('embedvideo-privacyNotice__link');

resources/modules/iframe.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ const fetchThumb = async (url, parent, container) => {
8282
title.classList.add('embedvideo-loader__title');
8383

8484
link.classList.add('embedvideo-loader__link');
85-
link.href = JSON.parse(container?.dataset?.iframeconfig ?? '{"src": "#"}').src;
85+
link.href = JSON.parse(container?.dataset?.mwIframeconfig ?? '{"src": "#"}').src;
8686
link.target = '_blank';
8787
link.rel = 'noopener noreferrer nofollow';
8888
link.innerText = json.title;
@@ -126,7 +126,7 @@ const makeIframe = function(ev) {
126126
const wrapper = ev.querySelector('.embedvideo-wrapper');
127127

128128
const getIframeConfig = function() {
129-
let iframeConfig = ev.dataset.iframeconfig;
129+
let iframeConfig = ev.dataset.mwIframeconfig;
130130

131131
iframeConfig = {
132132
...mw.config.get('ev-' + ev.dataset.service + '-config') ?? [],
@@ -176,7 +176,7 @@ const makeIframe = function(ev) {
176176

177177
/** @type HTMLDivElement|null */
178178
const consentDiv = wrapper.querySelector('.embedvideo-consent');
179-
let iframeConfig = ev.dataset.iframeconfig;
179+
let iframeConfig = ev.dataset.mwIframeconfig;
180180

181181
if (consentDiv === null || iframeConfig === null) {
182182
return;
@@ -206,4 +206,4 @@ const makeIframe = function(ev) {
206206
}
207207
}
208208

209-
module.exports = { makeIframe, fetchThumb }
209+
module.exports = { makeIframe, fetchThumb }

tests/phpunit/EmbedService/EmbedHtmlFormatterTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function testToHtmlConsent() {
4444
$service = EmbedServiceFactory::newFromName( 'archiveorg', 'foo' );
4545

4646
// phpcs:ignore Generic.Files.LineLength.TooLong
47-
$this->assertStringContainsString( 'data-iframeconfig=\'{"src":"//archive.org/embed/foo"}\'', EmbedHtmlFormatter::toHtml( $service ) );
47+
$this->assertStringContainsString( 'data-mw-iframeconfig=\'{"src":"//archive.org/embed/foo"}\'', EmbedHtmlFormatter::toHtml( $service ) );
4848
$this->assertStringNotContainsString( '<iframe', EmbedHtmlFormatter::toHtml( $service ) );
4949
}
5050

tests/phpunit/EmbedVideoTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public function testParseEVYouTubeValid() {
136136
$this->assertIsArray( $output );
137137
$this->assertCount( 3, $output );
138138
// phpcs:ignore Generic.Files.LineLength.TooLong
139-
$this->assertStringContainsString( '<figure class="embedvideo" data-service="youtube" data-iframeconfig=\'{"src":"https://www.youtube-nocookie.com/embed/foobar?autoplay=1"}\' style="width:640px">', $output[0] );
139+
$this->assertStringContainsString( '<figure class="embedvideo" data-service="youtube" data-mw-iframeconfig=\'{"src":"https://www.youtube-nocookie.com/embed/foobar?autoplay=1"}\' style="width:640px">', $output[0] );
140140
}
141141

142142
/**
@@ -308,7 +308,7 @@ public function testParseEVTagIdInInput() {
308308
$this->assertIsArray( $output );
309309
$this->assertCount( 3, $output );
310310
$this->assertStringContainsString(
311-
'<figure class="embedvideo" data-service="youtube" data-iframeconfig',
311+
'<figure class="embedvideo" data-service="youtube" data-mw-iframeconfig',
312312
$output[0]
313313
);
314314
}
@@ -339,7 +339,7 @@ public function testParseArgsExample1() {
339339
$this->assertIsArray( $output );
340340
$this->assertCount( 3, $output );
341341
$this->assertStringContainsString(
342-
'<figure class="embedvideo" data-service="youtube" data-iframeconfig',
342+
'<figure class="embedvideo" data-service="youtube" data-mw-iframeconfig',
343343
$output[0]
344344
);
345345
}
@@ -438,7 +438,7 @@ public function testParseEVLYouTube() {
438438
$this->assertIsArray( $output );
439439
$this->assertCount( 3, $output );
440440
// phpcs:ignore Generic.Files.LineLength.TooLong
441-
$this->assertStringContainsString( '<a data-iframeconfig="', $output[0] );
441+
$this->assertStringContainsString( '<a data-mw-iframeconfig="', $output[0] );
442442
$this->assertStringContainsString( 'Test Text', $output[0] );
443443
}
444444

0 commit comments

Comments
 (0)