1 (edited by carls 2011-08-20 13:25:42)

Topic: Element 'embed' enabled only for a few domains

Hi,

Is it possible to enable element "embed" only for a few domains and block the remaining? For example:

Enable:
http://vimeo.com
http://www.youtube.com

Block:
http://www.dailymotion.com
etc...

This is for security reasons, this way the users on my forum can not embed unsafe files. Thanks in advance!
Regards

2

Re: Element 'embed' enabled only for a few domains

Yes, it is possible to allow only certain domains within 'embed' elements. You have to set the $spec argument for htmLawed (see documentation on $spec). Below is a suggested value.

// only the rule for the 'src' attribute of  'embed' only
// rules for other attributes or elements can be added

// using 'match' property to allow white-listed domains
// 'nomatch' can be used instead or added as well to block black-listed domains

// backtick (`) is the regular expression pattern delimiter
// allowing for insensitive case matching
// for match 'src' value has to begin with 'http' or 'https'
// followed by '://' followed by optional 'www.'
// followed by 'youtube' or 'dailymotion' or 'vimeo' followed by '.com/'

$spec = 'embed=src(match="
      `^https?://(www\.)?((youtube)|(dailymotion)|(vimeo))\.com/`i
      ")';

This functionality relies on regular expression pattern-matching. If a match fails, the 'src' value is emptied... the of-no-use-now 'embed' still remains in the output. To remove such 'embed' altogether, you can process the htmLawed output using either separate custom code, which, for example, can regular expression-search and remove '<embed ... />' without 'src="..."' within it. Another option is to use htmLawed's hook_tag parameter because 'embed' is an "empty" element (no closing tag).

// define a custom function in $config argument for htmLawed
$config = array(..., 'hook_tag'=>'my_remove_empty_embed_function', ...);

// define 'my_remove_empty_embed_function' somewhere in your code
function my_remove_empty_embed_function(($element, $attribute_array=0){

  // if second argument is not received, it means a closing tag is being handled
  if(is_numeric($attribute_array)){
    return "</$element>";
  } 

  // empty return if element is 'embed' with no 'src' attribute value
  if($element='embed' && empty($attribute_array['src'])){
    return '';
  }

  // for everything else, return element with attributes

  // build the attributes string
  $attributes = '';
  foreach($attribute_array as $k=>$v){
    $attributes .= " {$k}=\"{$v}\"";
  }

  // return the opening tag with attributes
  static $empty_elements = array('area'=>1, 'br'=>1, 'col'=>1, 'embed'=>1, 'hr'=>1, 'img'=>1, 'input'=>1, 'isindex'=>1, 'param'=>1);
  return "<{$element}{$attributes}". (isset($empty_elements[$element]) ? ' /' : ''). '>';
}

Note that you can also use the 'hook_tag' functionality to achieve for 'embed' what is being achieved thorugh $spec above.