note 87956 deleted from function.strip-tags by danbrown
| From: | danbrown@php.net | Date: | Sun, 17 May 2009 15:49:59 +0000 |
| Subject: | note 87956 deleted from function.strip-tags by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-154701@lists.php.net to get a copy of this message | ||
Note Submitter: matt at lvi dot org
----
I have a correction for mdw252's whitelist-based stripAttributes function.
Using that function, if a user sends one of the following strings to the server, you get some
undesired output, with varying levels of severity:
1. xss vulnerablities:
<div onload..;,;.."xss.attack();">, <a
href="javascript:xss.attack();">, <div onclick=";xss.attack();">
2. some characters break the html:
<div style="border:1px solid blue;">
I believe that the function below takes care of those issues and is a little more flexible by
allowing some parameters.
By default, the function will strip all attributes. So, you could sanitize a string this way:
$string=stripAttributes($string);
To acheive the same as mdw252's function, which is to allow the id and class attributes as well
as href on links, you would:
$allowable = array('class','id');
$exceptions = array('a'=>'href');
$string=stripAttributes($string,$allowable,$exceptions);
Or, if you wanted to
- allow the "class" and "style" attributes generally,
- the "align" attribute only on table cells, and
- specify possible values for the align attribute,
you would:
$allowable = array('class','style');
$exceptions = array('table'=>'width','td'=>'align');
$values = array('align'=>array('left','center','right'));
$string=stripAttributes($string,$allowable,$exceptions,$values);
<?php
function stripAttributes($string, $allowable = NULL, $exceptions = NULL, $values = NULL,
$nohrefevents= true, $crs=NULL) {
$string=str_replace('..;,;..', '=', $string);
if (!$crs)
$crs = 'a-zA-Z0-9 \>\<\-:;\(\)\.\,\/=\&';
$string=preg_replace('/[^'.$crs.'\'"]/i','',$string);
$string=preg_replace('/(<.*) (.*=)(['.$crs.']*) (.*>)/', '${1}
${2}"${3}" ${4}', $string);
if ($nohrefevents)
$string=preg_replace('/(<a .* )href="(javascript:.*>)/',
'${1}onclick=${2}', $string);
//generally allowed attributes
if (is_array($allowable)){
foreach ($allowable as $allowed)
$string=preg_replace('/(<.* )'.$allowed.'=(.*>)/',
'${1}'.$allowed.'..;,;..${2}', $string);
}
//tag by tag exceptions
if (is_array($exceptions)){
foreach ($exceptions as $tag=>$attribute){
$string=preg_replace('/(<'.$tag.' ?.*
)'.$attribute.'=(.*>)/', '${1}'.$attribute.'..;,;..${2}',
$string);
}
}
//specified attribute values
if (is_array($values)){
foreach ($values as $attribute=>$value){
if (is_array($value)){
foreach ($value as $val)
while(preg_match('/(<.*)
'.$attribute.'=(\'|")'.$val.'(\'|".*>)/', $string))
$string=preg_replace('/(<.*)
'.$attribute.'=(\'|")'.$val.'(\'|".*>)/', '${1}
'.$attribute.'..;,;..${2}'.$val.'${3}', $string);
}
}
}
while(preg_match('/(<.*)
.*=(\'|")(['.$crs.']*)(\'|")(.*>)/', $string))
$string=preg_replace('/(<.*)
.*=(\'|")(['.$crs.']*)(\'|")(.*>)/', '${1}${5}',
$string);
$string=str_replace('..;,;..', '=', $string);
return $string;
}
?>