You are here

function ckeditor_filter_xss in CKEditor - WYSIWYG HTML editor 7

Same name and namespace in other branches
  1. 6 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 225
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() {
  header('Content-Type: text/plain; charset=utf-8');
  $GLOBALS['devel_shutdown'] = FALSE;
  if (!isset($_POST['text']) || !is_string($_POST['text']) || !isset($_POST['input_format']) || !is_string($_POST['input_format']) || !isset($_POST['token']) || !drupal_valid_token($_POST['token'], 'ckeditorAjaxCall', FALSE)) {
    exit;
  }
  $format = filter_format_load($_POST['input_format']);
  if ($format == FALSE || !is_object($format) || !filter_access($format)) {
    exit;
  }
  module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib');
  $text = $_POST['text'];
  $filters = filter_get_filters();
  $format_filters = filter_list_format($_POST['input_format']);
  $security_filters = ckeditor_security_filters();
  $cache_id = $_POST['input_format'] . ':' . '' . ':' . hash('sha256', $text);
  foreach ((array) $format_filters as $name => $object) {

    //If filter is not security filter, not exists, cannot be called or isn't enabled in selected text format then skip this filter
    if (!isset($security_filters['filters'][$name]) || !isset($filters[$name]) || !isset($filters[$name]['process callback']) || $object->status == 0) {
      continue;
    }

    // Built-in filter module, a special case where we would like to strip XSS and nothing more
    if ($name == 'filter_html' && $security_filters['filters']['filter_html'] == 1) {
      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+|<|>/', $object->settings['allowed_html'], -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);
      }
      continue;
    }
    if (isset($filters[$name]['prepare callback']) && function_exists($filters[$name]['prepare callback'])) {
      $text = $filters[$name]['prepare callback']($text, $format_filters[$name], $format, '', TRUE, $cache_id);
    }
    $text = $filters[$name]['process callback']($text, $format_filters[$name], $format, '', TRUE, $cache_id);
  }
  echo $text;
}