Adding enable_iframe_inclusion setting + htmlpurifier filter see #2159

skala
Julio Montoya 14 years ago
parent 55b5ca3ffa
commit bc3d66fdb5
  1. 2
      main/forum/viewpost.inc.php
  2. 46
      main/forum/viewthread_flat.inc.php
  3. 63
      main/inc/lib/htmlpurifier/library/HTMLPurifier/Filter/AllowIframes.php
  4. 54
      main/inc/lib/security.lib.php

@ -24,7 +24,7 @@ if (isset($rows)) {
if ($counter == 1) {
echo Display::page_subheader($name);
}
echo "<div ".$style."><table class=\"data_table\">";
// the style depends on the status of the message: approved or not
//echo 'dd'.$row['status'];

@ -17,10 +17,10 @@ if (isset($current_thread['thread_id'])){
$clean_forum_id = intval($_GET['forum']);
$clean_thread_id = intval($_GET['thread']);
$locked = api_resource_is_locked_by_gradebook($clean_thread_id, LINK_FORUM_THREAD);
$locked = api_resource_is_locked_by_gradebook($clean_thread_id, LINK_FORUM_THREAD);
foreach ($rows as $row) {
echo '<table width="100%" class="forum_table" cellspacing="5" border="0">';
// the style depends on the status of the message: approved or not
if ($row['visible']=='0') {
@ -34,14 +34,14 @@ if (isset($current_thread['thread_id'])){
}
echo "<tr>";
echo "<td rowspan=\"3\" class=\"$leftclass\">";
if ($row['user_id']=='0') {
$name = prepare4display($row['poster_name']);
} else {
$name = api_get_person_name($row['firstname'], $row['lastname']);
}
$username = sprintf(get_lang('LoginX'), $row['username']);
if ($origin!='learnpath') {
if (api_get_course_setting('allow_user_image_forum')) {
echo '<br />'.display_user_image($row['user_id'],$name).'<br />';
@ -52,7 +52,7 @@ if (isset($current_thread['thread_id'])){
}
$group_id = api_get_group_id();
echo api_convert_and_format_date($row['post_date']).'<br /><br />';
// get attach id
$attachment_list=get_attachment($row['post_id']);
@ -84,19 +84,19 @@ if (isset($current_thread['thread_id'])){
$user_status = api_get_status_of_user_in_course($row['user_id'], api_get_course_id());
$current_qualify_thread = show_qualify('1', $row['poster_id'],$_GET['thread']);
if (api_is_allowed_to_edit(null,true) && $origin != 'learnpath') {
$my_forum_id = $clean_forum_id;
if (isset($_GET['gradebook'])) {
if (isset($_GET['gradebook'])) {
$info_thread = get_thread_information($clean_thread_id);
$my_forum_id = $info_thread['forum_id'];
}
if ($increment > 0 && $locked == false) {
}
if ($increment > 0 && $locked == false) {
echo "<a href=\"forumqualify.php?".api_get_cidreq()."&amp;forum=".$my_forum_id."&amp;thread=".$clean_thread_id."&amp;action=list&amp;post=".$row['post_id']."&amp;user=".$row['poster_id']."&amp;user_id=".$row['poster_id']."&amp;origin=".$origin."&amp;idtextqualify=".$current_qualify_thread."&amp;gradebook=".Security::remove_XSS($_GET['gradebook'])."\" >".
Display::return_icon('quiz.gif',get_lang('Qualify'))."</a> ";
}
}
}
if (($current_forum_category && $current_forum_category['locked']==0) AND $current_forum['locked']==0 AND $current_thread['locked']==0 OR api_is_allowed_to_edit(false,true)) {
if ($_user['user_id'] OR ($current_forum['allow_anonymous']==1 AND !$_user['user_id'])) {
if (!api_is_anonymous() && api_is_allowed_to_session_edit(false,true)) {
@ -128,38 +128,40 @@ if (isset($current_thread['thread_id'])){
// The post title
echo "</tr>";
// The post title
echo "<tr>";
echo Display::tag('td', prepare4display($row['post_title']), array('class'=>'forum_message_post_title'));
echo "</tr>";
// The post message
echo "<tr>";
// see comments inside forumfunction.inc.php to lower filtering and allow more visual changes
echo "<td class=\"$messageclass\">".prepare4display($row['post_text'])."</td>";
echo "</tr>";
// The check if there is an attachment
$attachment_list=get_attachment($row['post_id']);
$attachment_list = get_attachment($row['post_id']);
if (!empty($attachment_list)) {
echo '<tr><td height="50%">';
echo '<tr><td colspan="2" height="50%">';
$realname=$attachment_list['path'];
$user_filename=$attachment_list['filename'];
echo Display::return_icon('attachment.gif',get_lang('Attachment'));
echo '<a href="download.php?file=';
echo $realname;
echo ' "> '.$user_filename.' </a>';
echo '<span class="forum_attach_comment" >'.$attachment_list['comment'].'</span>';
echo '<a href="download.php?file='.$realname.'"> '.$user_filename.' </a>';
if (($current_forum['allow_edit']==1 AND $row['user_id']==$_user['user_id']) or (api_is_allowed_to_edit(false,true) && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session']))) {
echo '&nbsp;&nbsp;<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;origin='.Security::remove_XSS($_GET['origin']).'&amp;action=delete_attach&amp;id_attach='.$attachment_list['id'].'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES)).'\')) return false;">'.Display::return_icon('delete.png',get_lang('Delete'), array(), ICON_SIZE_SMALL).'</a><br />';
echo '&nbsp;&nbsp;<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;origin='.Security::remove_XSS($_GET['origin']).'&amp;action=delete_attach&amp;id_attach='.$attachment_list['id'].'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES)).'\')) return false;">'.Display::return_icon('delete.png',get_lang('Delete'), array(), ICON_SIZE_SMALL).'</a><br />';
}
echo '<span class="forum_attach_comment" >'.$attachment_list['comment'].'</span>';
echo '</td></tr>';
}
// The post has been displayed => it can be removed from the what's new array
unset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$row['post_id']]);
unset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']]);

@ -0,0 +1,63 @@
<?php
/**
* Based on: http://stackoverflow.com/questions/4739284/htmlpurifier-iframe-vimeo-and-youtube-video
* Iframe filter that does some primitive whitelisting in a somewhat recognizable and tweakable way
*/
class HTMLPurifier_Filter_AllowIframes extends HTMLPurifier_Filter
{
public $name = 'AllowIframes';
/**
*
* @param string $html
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return string
*/
public function preFilter($html, HTMLPurifier_Config $config, HTMLPurifier_Context $context)
{
$html = preg_replace('#<iframe#i', '<img class="MyIframe"', $html);
$html = preg_replace('#</iframe>#i', '</img>', $html);
return $html;
}
/**
*
* @param string $html
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return string
*/
public function postFilter($html, HTMLPurifier_Config $config, HTMLPurifier_Context $context)
{
$post_regex = '#<img class="MyIframe"([^>]+?)>#';
return preg_replace_callback($post_regex, array($this, 'postFilterCallback'), $html);
}
/**
*
* @param array $matches
* @return string
*/
protected function postFilterCallback($matches)
{
// Domain Whitelist
$youTubeMatch = preg_match('#src="https?://www.youtube(-nocookie)?.com/#i', $matches[1]);
$vimeoMatch = preg_match('#src="http://player.vimeo.com/#i', $matches[1]);
$googleMapsMatch = preg_match('#src="https://maps.google.com/#i', $matches[1]);
if ($youTubeMatch || $vimeoMatch || $googleMapsMatch) {
$extra = ' frameborder="0"';
if ($youTubeMatch) {
$extra .= ' allowfullscreen';
} elseif ($vimeoMatch) {
$extra .= ' webkitAllowFullScreen mozallowfullscreen allowFullScreen';
}
return '<iframe ' . $matches[1] . $extra . '></iframe>';
} else {
return '';
}
}
}

@ -50,7 +50,7 @@ class Security {
$true_path = str_replace("\\", '/', realpath($abs_path));
$found = strpos($true_path.'/', $checker_path);
if ($found === 0) {
return true;
} else {
@ -260,7 +260,7 @@ class Security {
if ($filter_terms) {
$var = self::filter_terms($var);
}
if ($user_status == COURSEMANAGERLOWSECURITY) {
return $var; // No filtering.
}
@ -282,8 +282,13 @@ class Security {
$config->set('HTML.TidyLevel', 'light');
$config->set('Core.ConvertDocumentToFragment', false);
$config->set('Core.RemoveProcessingInstructions', true);
if (api_get_setting('enable_iframe_inclusion') == 'true') {
$config->set('Filter.Custom', array(new HTMLPurifier_Filter_AllowIframes()));
}
//Shows _target attribute in anchors
$config->set('Attr.AllowedFrameTargets', array('_blank','_top','_self', '_parent'));
$config->set('Attr.AllowedFrameTargets', array('_blank','_top','_self', '_parent'));
if ($user_status == STUDENT) {
global $allowed_html_student;
$config->set('HTML.SafeEmbed', true);
@ -308,52 +313,55 @@ class Security {
$config->set('CSS.Proprietary', true);
$purifier[$user_status] = new HTMLPurifier($config);
}
if (is_array($var)) {
return $purifier[$user_status]->purifyArray($var);
} else {
return $purifier[$user_status]->purify($var);
}
}
/**
*
* Filter content
*
* Filter content
* @param string content to be filter
* @return string
*/
function filter_terms($text) {
static $bad_terms = array();
if (empty($bad_terms)) {
$list = api_get_setting('filter_terms');
$list = explode("\n", $list);
$list = array_filter($list);
if (empty($bad_terms)) {
$list = api_get_setting('filter_terms');
$list = explode("\n", $list);
$list = array_filter($list);
if (!empty($list)) {
foreach($list as $term) {
$term = str_replace(array("\r\n", "\r", "\n", "\t"), '', $term);
$html_entities_value = api_htmlentities($term, ENT_QUOTES, api_get_system_encoding());
$html_entities_value = api_htmlentities($term, ENT_QUOTES, api_get_system_encoding());
$bad_terms[] = $term;
if ($term != $html_entities_value) {
if ($term != $html_entities_value) {
$bad_terms[] = $html_entities_value;
}
}
$bad_terms = array_filter($bad_terms);
}
}
$replace = '***';
$replace = '***';
if (!empty($bad_terms)) {
//Fast way
$new_text = str_ireplace($bad_terms, $replace, $text, $count);
//We need statistics
/*
if (strlen($new_text) != strlen($text)) {
$table = Database::get_main_table(TABLE_STATISTIC_TRACK_FILTERED_TERMS);
$attributes = array();
$attributes['user_id'] =
$attributes['course_id'] =
$attributes['session_id'] =
@ -364,11 +372,11 @@ class Security {
}
*/
$text = $new_text;
}
}
return $text;
}
/**
* This method provides specific protection (against XSS and other kinds of attacks) for static images (icons) used by the system.
@ -411,5 +419,5 @@ class Security {
return '';
}
return $image_path;
}
}
}

Loading…
Cancel
Save