Commit 4b8c5170 authored by Richard Mansfield's avatar Richard Mansfield
Browse files

Move the list of safe iframe sources to the database (bug #971282)



Builds the htmlpurifier safe iframe regexp from a list of sites stored
in the database, instead of a hardcoded array.

Each site in the safe iframe list is associated with a name.  This
will allow several regexp items to be grouped together under the same
name when they're matching urls from the same site.

Additionally, the domain part of each site is stored in a second list
along with the names, so that it will be easy to fetch the favicon for
display in places such as the external media block configuration form.

Change-Id: I7fd2bfefbff0881e70b94beb9e8d3efb43f0f9e7
Signed-off-by: default avatarRichard Mansfield <richard.mansfield@catalyst.net.nz>
parent 89f7ae64
......@@ -919,5 +919,24 @@
<KEY NAME="viewfk" TYPE="foreign" FIELDS="view" REFTABLE="view" REFFIELDS="id" />
</KEYS>
</TABLE>
<TABLE NAME="iframe_source_icon">
<FIELDS>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" />
<FIELD NAME="domain" TYPE="char" LENGTH="255" NOTNULL="true" />
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="name" />
</KEYS>
</TABLE>
<TABLE NAME="iframe_source">
<FIELDS>
<FIELD NAME="prefix" TYPE="char" LENGTH="255" NOTNULL="true" />
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" />
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="prefix" />
<KEY NAME="namefk" TYPE="foreign" FIELDS="name" REFTABLE="iframe_source_icon" REFFIELDS="name" />
</KEYS>
</TABLE>
</TABLES>
</XMLDB>
......@@ -2829,5 +2829,50 @@ function xmldb_core_upgrade($oldversion=0) {
reload_html_filters();
}
if ($oldversion < 2012032300) {
// Tables for configurable safe iframe sources
$table = new XMLDBTable('iframe_source_icon');
$table->addFieldInfo('name', XMLDB_TYPE_CHAR, 255, null, XMLDB_NOTNULL);
$table->addFieldInfo('domain', XMLDB_TYPE_CHAR, 255, null, XMLDB_NOTNULL);
$table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('name'));
create_table($table);
$iframedomains = array(
'YouTube' => 'www.youtube.com',
'Vimeo' => 'vimeo.com',
'SlideShare' => 'www.slideshare.net',
'Glogster' => 'www.glogster.com',
'WikiEducator' => 'wikieducator.org',
);
foreach ($iframedomains as $name => $domain) {
insert_record('iframe_source_icon', (object) array('name' => $name, 'domain' => $domain));
}
$table = new XMLDBTable('iframe_source');
$table->addFieldInfo('prefix', XMLDB_TYPE_CHAR, 255, null, XMLDB_NOTNULL);
$table->addFieldInfo('name', XMLDB_TYPE_CHAR, 255, null, XMLDB_NOTNULL);
$table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('prefix'));
$table->addKeyInfo('namefk', XMLDB_KEY_FOREIGN, array('name'), 'iframe_source_icon', array('name'));
create_table($table);
$iframesources = array(
'www.youtube.com/embed/' => 'YouTube',
'player.vimeo.com/video/' => 'Vimeo',
'www.slideshare.net/slideshow/embed_code/' => 'SlideShare',
'www.glogster.com/glog/' => 'Glogster',
'www.glogster.com/glog.php' => 'Glogster',
'edu.glogster.com/glog/' => 'Glogster',
'edu.glogster.com/glog.php' => 'Glogster',
'wikieducator.org/index.php' => 'WikiEducator',
);
foreach ($iframesources as $prefix => $name) {
insert_record('iframe_source', (object) array('prefix' => $prefix, 'name' => $name));
}
$iframeregexp = '%^https?://(' . str_replace('.', '\.', implode('|', array_keys($iframesources))) . ')%';
set_config('iframeregexp', $iframeregexp);
}
return $status;
}
......@@ -643,6 +643,27 @@ function core_postinst() {
set_antispam_defaults();
reload_html_filters();
// Default set of sites from which iframe content can be embedded
$iframesources = array(
'www.youtube.com/embed/' => 'YouTube',
'player.vimeo.com/video/' => 'Vimeo',
'www.slideshare.net/slideshow/embed_code/' => 'SlideShare',
'www.glogster.com/glog/' => 'Glogster',
'www.glogster.com/glog.php' => 'Glogster',
'edu.glogster.com/glog/' => 'Glogster',
'edu.glogster.com/glog.php' => 'Glogster',
'wikieducator.org/index.php' => 'WikiEducator',
);
$iframedomains = array(
'YouTube' => 'www.youtube.com',
'Vimeo' => 'vimeo.com',
'SlideShare' => 'www.slideshare.net',
'Glogster' => 'www.glogster.com',
'WikiEducator' => 'wikieducator.org',
);
update_safe_iframes($iframesources, $iframedomains);
return $status;
}
......@@ -1094,6 +1115,41 @@ function reload_html_filters() {
log_info('Enabled ' . count($filters) . ' HTML filters.');
}
function update_safe_iframe_regex() {
$prefixes = get_column('iframe_source', 'prefix');
if (!empty($prefixes)) {
// We must generate a guaranteed valid regex here that's not
// too slack. It's easiest to whitelist a few characters, but
// in future we may need to be more clever. Admins who know
// what they're doing, and need something fancy, can always
// override this in config.php.
foreach ($prefixes as $r) {
if (!preg_match('/^[a-zA-Z0-9\/\._-]+$/', $r)) {
throw new SystemException('Invalid site passed to update_safe_iframe_regex');
}
}
$iframeregexp = '%^https?://(' . str_replace('.', '\.', implode('|', $prefixes)) . ')%';
}
set_config('iframeregexp', isset($iframeregexp) ? $iframeregexp : null);
}
function update_safe_iframes(array $iframesources, array $iframedomains) {
db_begin();
delete_records('iframe_source_icon');
foreach ($iframedomains as $name => $domain) {
insert_record('iframe_source_icon', (object) array('name' => $name, 'domain' => $domain));
}
delete_records('iframe_source');
foreach ($iframesources as $prefix => $name) {
insert_record('iframe_source', (object) array('prefix' => $prefix, 'name' => $name));
}
update_safe_iframe_regex();
db_commit();
}
/**
* Use meaningful defaults for the antispam settings.
*/
......
......@@ -28,7 +28,7 @@
defined('INTERNAL') || die();
$config = new StdClass;
$config->version = 2012022100;
$config->version = 2012032300;
$config->release = '1.6.0dev';
$config->minupgradefrom = 2008040200;
$config->minupgraderelease = '1.0.0 (release tag 1.0.0_RELEASE)';
......
......@@ -2729,19 +2729,13 @@ function clean_html($text, $xhtml=false) {
}
// Permit embedding contents from other sites
// List of pattern fragments for the URI.SafeIframeRegexp below
$safeiframesources = array('www\.youtube\.com/embed/',
'player\.vimeo\.com/video/',
'www\.slideshare\.net/slideshow/embed_code/',
'(www|edu)\.glogster\.com/glog(/|\.php)',
'wikieducator\.org/index\.php',
);
$config->set('HTML.SafeEmbed', true);
$config->set('HTML.SafeObject', true);
$config->set('Output.FlashCompat', true);
$config->set('HTML.SafeIframe', true);
$config->set('URI.SafeIframeRegexp',
'%^https?://('.implode('|', $safeiframesources).')%');
if ($iframeregexp = get_config('iframeregexp')) {
$config->set('HTML.SafeIframe', true);
$config->set('URI.SafeIframeRegexp', $iframeregexp);
}
// Allow namespaced IDs
// see http://htmlpurifier.org/docs/enduser-id.html
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment