note 94479 deleted from function.strip-tags by danbrown

From: Date: Sat, 07 Nov 2009 18:34:32 +0000
Subject: note 94479 deleted from function.strip-tags by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-162487@lists.php.net to get a copy of this message
Note Submitter: abel at wayfarerweb dot com ---- I rewrote the strip_tags_attributes function below, because it didn't function intuitively enough for my purposes. In the previous example, if the $allowattributes argument is left blank, intead of all attributes being stripped, none of them will be stripped. This is quite the opposite of what is expected, since nothing was allowed. <?php function strip_tags_attributes($string,$allowtags='',$allowattributes=''){ $string = strip_tags($string, $allowtags); if(!empty($allowtags)) {//if no tags are allowed, all attributes are stripped anyway if(!is_array($allowattributes)) $allowattributes = explode(",", $allowattributes); if(is_array($allowattributes)) $allowattributes = implode(")(?<!", $allowattributes); if (strlen($allowattributes) > 0) $allowattributes = "(?<!".$allowattributes.")"; $char = (strlen($allowattributes) > 0) ? '[^ =\'\"]*' : ' ?[^ =]*'; $string = preg_replace_callback("/<[^>]*>/i",create_function( '$matches', 'return preg_replace("/'.$char.$allowattributes.'=(\"[^\"]*\"|\'[^\']*\')/i", "", $matches[0]);' ),$string); } return $string; } ?> I also modified the regular expression being fed to the anonymous function. This is because previously, including attributes together without a space between them would result in a tag made up of the attribute merged together with the tag. Using previous function: <?php $string = '<p onmouseover="alert(\'hello\')"onclick="alert(\'click\')">Test</p>'; $string = strip_tags_attributes($string,'<p>', '');//attempt to strip all attributes echo $string; ?> Would result in this: <ponclick="alert(\'click\')">Test</p> Although this is non-functional it should have been removed. With the new function, this becomes: <p>Test</p> Also, with the previous function it is possible to inject an unwanted attribute into a tag if any attributes are allowed at all, just by not including a space between them. This is a serious security risk. Example: <?php $string = '<p style="font-weight:bold;"onmouseover="do_evil_function()">XSS</p>'; $string = strip_tags_attributes($string, '<p>', 'style'); echo $string; ?> Results in: <p style="font-weight:bold;"onmouseover="do_evil_function()">XSS</p> Counting on there being spaces between attributes is not good. Also, the previous function had problems any time there were spaces inside of the attributes. This is common in style attributes, for example. The only downside to my function as far as I can tell, since it pretty much ignores spaces when matching, is that is sometimes leaves some extra space behind in the tag when removing attributes. Usage: <?php strip_tags_attributes($string);//strip all tags and attributes strip_tags_attributes($string, '<strong><em>');//allow selected tags, strip all attributes strip_tags_attributes($string,'<strong><em><a>','href,rel');//allow selected tags, selected attributes ?>

« previous php.notes (#162487) next »