Commit a0d3e32a authored by Sara Arjona's avatar Sara Arjona
Browse files

MDL-72042 media: Remove SWF media player

The Flash Player was deprecated in 2017 and officially discontinued
on 31 December 2020, so media_swf player has been completely
removed from Moodle core.
parent 5ea35451
......@@ -42,7 +42,7 @@ print $OUTPUT->header();
// Enable all players.
$enabledmediaplugins = \core\plugininfo\media::get_enabled_plugins();
\core\plugininfo\media::set_enabled_plugins('vimeo,youtube,videojs,html5audio,html5video,swf');
\core\plugininfo\media::set_enabled_plugins('vimeo,youtube,videojs,html5audio,html5video');
// Create plugin.
$filterplugin = new filter_mediaplugin(null, array());
......@@ -153,4 +153,4 @@ filter_mediaplugin_perf_stop('One link (mp3)');
// End page.
echo html_writer::end_tag('ul');
print $OUTPUT->footer();
\ No newline at end of file
print $OUTPUT->footer();
......@@ -74,7 +74,7 @@ class filter_mediaplugin extends moodle_text_filter {
return $text;
}
// Check SWF permissions.
// Check permissions.
$this->trusted = !empty($options['noclean']) or !empty($CFG->allowobjectembed);
// Looking for tags.
......@@ -177,7 +177,7 @@ class filter_mediaplugin extends moodle_text_filter {
*/
protected function embed_alternatives($urls, $name, $width, $height, $options) {
// Allow SWF (or not).
// Allow trusted content (or not).
if ($this->trusted) {
$options[core_media_manager::OPTION_TRUSTED] = true;
}
......
......@@ -34,8 +34,8 @@ class filter_mediaplugin_testcase extends advanced_testcase {
function test_filter_mediaplugin_link() {
$this->resetAfterTest(true);
// we need to enable the plugins somehow and the flash fallback.
\core\plugininfo\media::set_enabled_plugins('vimeo,youtube,videojs,html5video,swf,html5audio');
// We need to enable the media plugins.
\core\plugininfo\media::set_enabled_plugins('vimeo,youtube,videojs,html5video,html5audio');
set_config('useflash', true, 'media_videojs');
$filterplugin = new filter_mediaplugin(null, array());
......
......@@ -826,8 +826,6 @@ $string['mediapluginogv'] = 'Enable .ogv filter';
$string['mediapluginram'] = 'Enable .ram filter';
$string['mediapluginrm'] = 'Enable .rm filter';
$string['mediapluginrpm'] = 'Enable .rpm filter';
$string['mediapluginswf'] = 'Enable .swf filter';
$string['mediapluginswfnote'] = 'As a default security measure, normal users should not be allowed to embed swf flash files.';
$string['mediapluginwmv'] = 'Enable .wmv filter';
$string['mediapluginyoutube'] = 'Enable YouTube links filter';
$string['messaging'] = 'Enable messaging system';
......@@ -1552,3 +1550,6 @@ $string['modchooserdefault'] = 'Activity chooser default';
// Deprecated since Moodle 4.0.
$string['coursepage'] = 'Course page';
$string['mediapluginswf'] = 'Enable .swf filter';
$string['mediapluginswfnote'] = 'As a default security measure, normal users should not be allowed to embed swf flash files.';
......@@ -159,3 +159,5 @@ importfrominstructions,core_calendar
proceedtocourse,core_enrol
coursepage,core_admin
invalidpersistenterror,core_competency
mediapluginswf,core_admin
mediapluginswfnote,core_admin
......@@ -126,7 +126,6 @@ class manager {
new environment\publicpaths(),
new environment\configrw(),
new environment\preventexecpath(),
new security\mediafilterswf(),
new security\embed(),
new security\openprofiles(),
new security\crawlers(),
......@@ -156,4 +155,3 @@ class manager {
return $checks;
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Verifies sloppy swf embedding - this should have been removed long ago!!
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\security;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Verifies sloppy swf embedding - this should have been removed long ago!!
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mediafilterswf extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_mediafilterswf_name', 'report_security');
}
/**
* A link to a place to action this
*
* @return action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/settings.php?section=managemediaplayers'),
get_string('managemediaplayers', 'media'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
$details = get_string('check_mediafilterswf_details', 'report_security');
$activefilters = filter_get_globally_enabled();
$enabledmediaplayers = \core\plugininfo\media::get_enabled_plugins();
if (array_search('mediaplugin', $activefilters) !== false and array_key_exists('swf', $enabledmediaplayers)) {
$status = result::CRITICAL;
$summary = get_string('check_mediafilterswf_error', 'report_security');
} else {
$status = result::OK;
$summary = get_string('check_mediafilterswf_ok', 'report_security');
}
return new result($status, $summary, $details);
}
}
......@@ -260,8 +260,8 @@ abstract class core_filetypes {
'svgz' => array('type' => 'image/svg+xml', 'icon' => 'image',
'groups' => array('image', 'web_image'), 'string' => 'image'),
'swa' => array('type' => 'application/x-director', 'icon' => 'flash'),
'swf' => array('type' => 'application/x-shockwave-flash', 'icon' => 'flash', 'groups' => array('video', 'web_video')),
'swfl' => array('type' => 'application/x-shockwave-flash', 'icon' => 'flash', 'groups' => array('video', 'web_video')),
'swf' => array('type' => 'application/x-shockwave-flash', 'icon' => 'flash'),
'swfl' => array('type' => 'application/x-shockwave-flash', 'icon' => 'flash'),
'sxw' => array('type' => 'application/vnd.sun.xml.writer', 'icon' => 'writer'),
'stw' => array('type' => 'application/vnd.sun.xml.writer.template', 'icon' => 'writer'),
......
......@@ -1725,6 +1725,7 @@ class core_plugin_manager {
'block' => array('course_overview', 'messages', 'community', 'participants'),
'cachestore' => array('memcache'),
'enrol' => array('authorize'),
'media' => array('swf'),
'qformat' => array('webct'),
'message' => array('jabber'),
'quizaccess' => array('safebrowser'),
......@@ -1908,7 +1909,7 @@ class core_plugin_manager {
),
'media' => array(
'html5audio', 'html5video', 'swf', 'videojs', 'vimeo', 'youtube'
'html5audio', 'html5video', 'videojs', 'vimeo', 'youtube'
),
'message' => array(
......
......@@ -131,7 +131,7 @@ function xmldb_main_install() {
'filterall' => 0, // setting page, so have to be initialised here.
'texteditors' => 'atto,tinymce,textarea',
'antiviruses' => '',
'media_plugins_sortorder' => 'videojs,youtube,swf',
'media_plugins_sortorder' => 'videojs,youtube',
'upgrade_extracreditweightsstepignored' => 1, // New installs should not run this upgrade step.
'upgrade_calculatedgradeitemsignored' => 1, // New installs should not run this upgrade step.
'upgrade_letterboundarycourses' => 1, // New installs should not run this upgrade step.
......
......@@ -2778,5 +2778,15 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2021091100.02);
}
if ($oldversion < 2021091700.01) {
// Remove media_swf (unless it has manually been added back).
if (!file_exists($CFG->dirroot . '/media/player/swf/classes/plugin.php')) {
unset_all_config_for_plugin('media_swf');
}
// Main savepoint reached.
upgrade_main_savepoint(true, 2021091700.01);
}
return true;
}
......@@ -142,10 +142,10 @@ class core_medialib_testcase extends advanced_testcase {
$manager = core_media_manager::instance();
$this->assertSame('youtube, html5audio', $this->get_players_test($manager));
// Test SWF and HTML5 media order.
\core\plugininfo\media::set_enabled_plugins('html5video,html5audio,swf');
// Test HTML5 media order.
\core\plugininfo\media::set_enabled_plugins('html5video,html5audio');
$manager = core_media_manager::instance();
$this->assertSame('html5video, html5audio, swf', $this->get_players_test($manager));
$this->assertSame('html5video, html5audio', $this->get_players_test($manager));
// Make sure that our test plugin is considered installed.
\core\plugininfo\media::set_enabled_plugins('test,html5video');
......@@ -181,11 +181,6 @@ class core_medialib_testcase extends advanced_testcase {
\core\plugininfo\media::set_enabled_plugins('html5video');
$manager = core_media_manager::instance();
$this->assertTrue($manager->can_embed_url($url));
// Only SWF.
\core\plugininfo\media::set_enabled_plugins('swf');
$manager = core_media_manager::instance();
$this->assertFalse($manager->can_embed_url($url));
}
/**
......@@ -195,7 +190,6 @@ class core_medialib_testcase extends advanced_testcase {
public function test_embed_url_fallbacks() {
// Key strings in the embed code that identify with the media formats being tested.
$swf = '</object>';
$html5video = '</video>';
$html5audio = '</audio>';
$link = 'mediafallbacklink';
......@@ -218,7 +212,7 @@ class core_medialib_testcase extends advanced_testcase {
$this->assertStringContainsString($link, $t);
// Enable media players that can play the same media formats. (ie. test & html5audio for mp3 files, etc.)
\core\plugininfo\media::set_enabled_plugins('test,html5video,html5audio,swf');
\core\plugininfo\media::set_enabled_plugins('test,html5video,html5audio');
$manager = core_media_manager::instance();
// Test media formats that can be played by 2 or more players.
......@@ -234,13 +228,11 @@ class core_medialib_testcase extends advanced_testcase {
$this->assertStringContainsString($test, $textwithlink);
$this->assertStringNotContainsString($html5video, $textwithlink);
$this->assertStringContainsString($html5audio, $textwithlink);
$this->assertStringNotContainsString($swf, $textwithlink);
$this->assertStringContainsString($link, $textwithlink);
$this->assertStringContainsString($test, $textwithoutlink);
$this->assertStringNotContainsString($html5video, $textwithoutlink);
$this->assertStringContainsString($html5audio, $textwithoutlink);
$this->assertStringNotContainsString($swf, $textwithoutlink);
$this->assertStringNotContainsString($link, $textwithoutlink);
break;
......@@ -248,13 +240,11 @@ class core_medialib_testcase extends advanced_testcase {
$this->assertStringContainsString($test, $textwithlink);
$this->assertStringContainsString($html5video, $textwithlink);
$this->assertStringNotContainsString($html5audio, $textwithlink);
$this->assertStringNotContainsString($swf, $textwithlink);
$this->assertStringContainsString($link, $textwithlink);
$this->assertStringContainsString($test, $textwithoutlink);
$this->assertStringContainsString($html5video, $textwithoutlink);
$this->assertStringNotContainsString($html5audio, $textwithoutlink);
$this->assertStringNotContainsString($swf, $textwithoutlink);
$this->assertStringNotContainsString($link, $textwithoutlink);
break;
......@@ -266,10 +256,9 @@ class core_medialib_testcase extends advanced_testcase {
/**
* Test for embed_url.
* Check SWF works including the special option required to enable it
* SWF shouldn't be converted to objects because media_swf has been removed.
*/
public function test_embed_url_swf() {
\core\plugininfo\media::set_enabled_plugins('swf');
$manager = core_media_manager::instance();
// Without any options...
......@@ -280,7 +269,7 @@ class core_medialib_testcase extends advanced_testcase {
// ...and with the 'no it's safe, I checked it' option.
$url = new moodle_url('http://example.org/test.swf');
$t = $manager->embed_url($url, '', 0, 0, array(core_media_manager::OPTION_TRUSTED => true));
$this->assertStringContainsString('</object>', $t);
$this->assertStringNotContainsString('</object>', $t);
}
/**
......
......@@ -89,6 +89,8 @@ information provided here is intended especially for developers.
DB call on every request.
* As the message_jabber notification plugin has been moved to the plugins database, the XMPPHP library (aka Jabber) has been
completely removed from Moodle core too.
* The SWF media player has been completely removed (The Flash Player was deprecated in 2017 and officially discontinued
on 31 December 2020).
=== 3.11.2 ===
* For security reasons, filelib has been updated so all requests now use emulated redirects.
......
......@@ -66,7 +66,8 @@ final class core_media_manager {
* Option: Enable players which are only suitable for use when we trust the
* user who embedded the content.
*
* At present, this option enables the SWF player.
* In the past, this option enabled the SWF player (which was removed).
* However, this setting will remain because it might be used by third-party plugins.
*
* To enable, set value to true.
*/
......
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Main class for plugin 'media_swf'
*
* @package media_swf
* @copyright 2016 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Media player for Flash SWF files.
*
* This player contains additional security restriction: it will only be used
* if you add option core_media_player_swf::ALLOW = true.
*
* Code should only set this option if it has verified that the data was
* embedded by a trusted user (e.g. in trust text).
*
* @package media_swf
* @copyright 2016 Marina Glancy
* @author 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class media_swf_plugin extends core_media_player {
public function embed($urls, $name, $width, $height, $options) {
self::pick_video_size($width, $height);
$firsturl = reset($urls);
$url = $firsturl->out(true);
$fallback = core_media_player::PLACEHOLDER;
$output = <<<OET
<span class="mediaplugin mediaplugin_swf">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="$width" height="$height">
<param name="movie" value="$url" />
<param name="autoplay" value="true" />
<param name="loop" value="false" />
<param name="controller" value="true" />
<param name="scale" value="aspect" />
<param name="base" value="." />
<param name="allowscriptaccess" value="never" />
<param name="allowfullscreen" value="true" />
<!--[if !IE]><!-->
<object type="application/x-shockwave-flash" data="$url" width="$width" height="$height">
<param name="controller" value="true" />
<param name="autoplay" value="true" />
<param name="loop" value="false" />
<param name="scale" value="aspect" />
<param name="base" value="." />
<param name="allowscriptaccess" value="never" />
<param name="allowfullscreen" value="true" />
<!--<![endif]-->
$fallback
<!--[if !IE]><!-->
</object>
<!--<![endif]-->
</object>
</span>
OET;
return $output;
}
public function get_supported_extensions() {
return array('.swf');
}
public function list_supported_urls(array $urls, array $options = array()) {
// Not supported unless the creator is trusted.
if (empty($options[core_media_manager::OPTION_TRUSTED])) {
return array();
}
return parent::list_supported_urls($urls, $options);
}
/**
* Default rank
* @return int
*/
public function get_rank() {
return 30;
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Privacy provider implementation for media_swf.
*
* @package media_swf
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace media_swf\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy provider implementation for media_swf.
*
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Strings for plugin 'media_swf'
*
* @package media_swf
* @copyright 2016 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['pluginname'] = 'Flash animation';
$string['pluginname_help'] = 'For security reasons this format is only embedded within trusted text.';
$string['privacy:metadata'] = 'The Flash animation media plugin does not store any personal data.';
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Test classes for handling embedded media.
*
* @package media_swf
* @copyright 2016 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Test script for media embedding.
*
* @package media_swf
* @copyright 2016 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class media_swf_testcase extends advanced_testcase {
/**
* Pre-test setup. Preserves $CFG.
*/
public function setUp(): void {
global $CFG;
parent::setUp();
// Reset $CFG and $SERVER.
$this->resetAfterTest();
// We need trusttext for embedding swf.
$CFG->enabletrusttext = true;
// Consistent initial setup: all players disabled.
\core\plugininfo\media::set_enabled_plugins('swf');
// Pretend to be using Firefox browser (must support ogg for tests to work).
core_useragent::instance(true, 'Mozilla/5.0 (X11; Linux x86_64; rv:46.0) Gecko/20100101 Firefox/46.0 ');
}
/**
* Test that plugin is returned as enabled media plugin.
*/
public function test_is_installed() {
$sortorder = \core\plugininfo\media::get_enabled_plugins();
$this->assertEquals(['swf' => 'swf'], $sortorder);
}
/**
* Test embedding without media filter (for example for displaying file resorce).
*/
public function test_embed_url() {
global $CFG;
$url = new moodle_url('http://example.org/1.swf');
$manager = core_media_manager::instance();
$embedoptions = array(
core_media_manager::OPTION_TRUSTED => true,
core_media_manager::OPTION_BLOCK => true,
);
$this->assertTrue($manager->can_embed_url($url, $embedoptions));
$content = $manager->embed_url($url, 'Test & file', 0, 0, $embedoptions);
$this->assertMatchesRegularExpression('~mediaplugin_swf~', $content);
$this->assertMatchesRegularExpression('~</object>~', $content);
$this->assertMatchesRegularExpression('~width="' . $CFG->media_default_width . '" height="' .
$CFG->media_default_height . '"~', $content);
// Repeat sending the specific size to the manager.
$content = $manager->embed_url($url, 'New file', 123, 50, $embedoptions);
$this->assertMatchesRegularExpression('~width="123" height="50"~', $content);
// Not working without trust!
$embedoptions = array(
core_media_manager::OPTION_BLOCK => true,
);
$this->assertFalse($manager->can_embed_url($url, $embedoptions));
$content = $manager->embed_url($url, 'Test & file', 0, 0, $embedoptions);
$this->assertDoesNotMatchRegularExpression('~mediaplugin_swf~', $content);
}
/**
* Test that mediaplugin filter replaces a link to the supported file with media tag.
*
* filter_mediaplugin is enabled by default.
*/
public function test_embed_link() {
global $CFG;
$url = new moodle_url('http://example.org/some_filename.swf');