function ckeditor_filter_xss in CKEditor - WYSIWYG HTML editor 6
Same name and namespace in other branches
- 7 includes/ckeditor.page.inc \ckeditor_filter_xss()
AJAX callback - XSS filter
1 string reference to 'ckeditor_filter_xss'
- ckeditor_menu in ./
ckeditor.module - Implementation of hook_menu().
File
- includes/
ckeditor.page.inc, line 282 - CKEditor - The text editor for the Internet - http://ckeditor.com Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
Code
function ckeditor_filter_xss() {
global $user, $theme;
header('Content-Type: text/plain; charset=utf-8');
$GLOBALS['devel_shutdown'] = FALSE;
if (!isset($_POST['text']) || !is_string($_POST['text']) || !isset($_POST['textarea_id']) || !is_string($_POST['textarea_id']) || !isset($_POST['query']) || !is_string($_POST['query']) || !isset($_POST['theme']) || !is_string($_POST['theme']) || !isset($_POST['input_format']) || !isset($_POST['token']) || !drupal_valid_token($_POST['token'], 'ckeditorAjaxCall', FALSE)) {
exit;
}
$filter_format_id = filter_resolve_format((int) $_POST['input_format']);
if (!filter_access($filter_format_id)) {
exit;
}
module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib');
$theme = $_POST['theme'];
$profile = ckeditor_user_get_profile($user, $_POST['textarea_id'], $_POST['query']);
if ($profile == FALSE) {
exit;
}
$settings = $profile->settings;
$text = $_POST['text'];
$text = strtr($text, array(
'<!--' => '__COMMENT__START__',
'-->' => '__COMMENT__END__',
));
$filters = array();
foreach ($settings['filters'] as $module_delta => $active) {
if (!$active || !is_string($module_delta)) {
continue;
}
$filter = new stdClass();
$filter->module = strtok($module_delta, "/");
$filter->delta = strtok("/");
$filter->format = $filter_format_id;
if (!module_hook($filter->module, 'filter')) {
continue;
}
$filters[] = $filter;
$text = module_invoke($filter->module, 'filter', 'prepare', $filter->delta, $filter->format, $text);
}
foreach ($filters as $filter) {
// Built-in filter module, a special case where we would like to strip XSS and nothing more
if ($filter->module == 'filter' && $filter->delta == 0) {
preg_match_all("|</?([a-z][a-z0-9]*)(?:\\b[^>]*)>|i", $text, $matches);
if ($matches[1]) {
// Sources of inspiration:
// http://www.w3.org/TR/html4/index/elements.html
// http://www.w3.org/TR/html-markup/elements.html
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element
$base_allowed_tags = array(
'a',
'abbr',
'acronym',
'address',
'area',
'article',
'aside',
'audio',
'b',
'base',
'basefont',
'bdi',
'bdo',
'big',
'blockquote',
'body',
'br',
'button',
'canvas',
'caption',
'center',
'cite',
'code',
'col',
'colgroup',
'command',
'datalist',
'dd',
'del',
'details',
'dfn',
'dialog',
'dir',
'div',
'dl',
'dt',
'em',
'fieldset',
'figcaption',
'figure',
'font',
'footer',
'form',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'head',
'header',
'hgroup',
'hr',
'html',
'i',
'img',
'input',
'ins',
'isindex',
'kbd',
'keygen',
'label',
'legend',
'li',
'main',
'map',
'mark',
'menu',
'menuitem',
'meter',
'nav',
'noframes',
'noscript',
'ol',
'optgroup',
'option',
'output',
'p',
'param',
'pre',
'progress',
'q',
'rp',
'rt',
'ruby',
's',
'samp',
'section',
'select',
'small',
'source',
'span',
'strike',
'strong',
'sub',
'summary',
'sup',
'table',
'tbody',
'td',
'textarea',
'tfoot',
'th',
'thead',
'time',
'title',
'tr',
'track',
'tt',
'u',
'ul',
'var',
'video',
'wbr',
);
// Get tags allowed in filter settings
$filter_allowed_tags = preg_split('/\\s+|<|>/', variable_get("allowed_html_{$filter_format_id}", ''), -1, PREG_SPLIT_NO_EMPTY);
// Combine allowed tags
$tags = array_merge($base_allowed_tags, $filter_allowed_tags);
// Tags provided by hook
$hooks_allowed_tags = module_invoke_all('ckeditor_filter_xss_allowed_tags');
if (!empty($hooks_allowed_tags) && is_array($hooks_allowed_tags)) {
foreach ($hooks_allowed_tags as $tag) {
if (!empty($tag) && is_string($tag) && !in_array($tag, $tags)) {
array_push($tags, $tag);
}
}
}
$text = filter_xss($text, $tags);
}
}
else {
$text = module_invoke($filter->module, 'filter', 'process', $filter->delta, $filter->format, $text);
}
}
$text = strtr($text, array(
'__COMMENT__START__' => '<!--',
'__COMMENT__END__' => '-->',
));
echo $text;
exit;
}