strip_tags()
documentation告诉我们除了第二个参数中的标签之外的所有标签都被剥离。此函数执行的操作与其名称完全相反。它应该被命名为strip_all_tags_except()
。
让我们忘记这个名字,然后来看看我想问的问题。我想要只删除我在第二个参数中提到的标签的功能。即。我希望以下内容删除标记<iframe><script><style><embed><object>
并允许所有其他标记。
my_strip_tags($data,'<iframe><script><style><embed><object>');
与strip_tags()
的做法完全相反。
我该如何实现?
答案 0 :(得分:3)
根本不应该发生。
strip_tags
仅在没有任何参数的情况下使用。否则,您将在允许的任何标记中使用XSS。
事实上,您的关注不仅应该是标签,还应该是属性。因此,请使用某种HTML净化器。
答案 1 :(得分:3)
更新2012-06-23;主要的安全漏洞。
这是来自另一个应该做你正在寻找的项目的课程:
final class Filter {
private function __construct() {}
const SafeTags = 'a abbr acronym address b bdo big blockquote br caption center cite code col colgroup dd del dfn dir div dl dt em font h1 h2 h3 h4 h5 h6 hr i img ins kbd legend li ol p pre q s samp small span strike strong sub sup table tbody td tfoot th thead tr tt u ul var article aside figure footer header nav section rp rt ruby dialog hgroup mark time';
const SafeAttributes = 'href src title alt type rowspan colspan lang';
const URLAttributes = 'href src';
public static function HTML($html) {
# Get array representations of the safe tags and attributes:
$safeTags = explode(' ', self::SafeTags);
$safeAttributes = explode(' ', self::SafeAttributes);
$urlAttributes = explode(' ', self::URLAttributes);
# Parse the HTML into a document object:
$dom = new DOMDocument();
$dom->loadHTML('<div>' . $html . '</div>');
# Loop through all of the nodes:
$stack = new SplStack();
$stack->push($dom->documentElement);
while($stack->count() > 0) {
# Get the next element for processing:
$element = $stack->pop();
# Add all the element's child nodes to the stack:
foreach($element->childNodes as $child) {
if($child instanceof DOMElement) {
$stack->push($child);
}
}
# And now, we do the filtering:
if(!in_array(strtolower($element->nodeName), $safeTags)) {
# It's not a safe tag; unwrap it:
while($element->hasChildNodes()) {
$element->parentNode->insertBefore($element->firstChild, $element);
}
# Finally, delete the offending element:
$element->parentNode->removeChild($element);
} else {
# The tag is safe; now filter its attributes:
for($i = 0; $i < $element->attributes->length; $i++) {
$attribute = $element->attributes->item($i);
$name = strtolower($attribute->name);
if(!in_array($name, $safeAttributes) || (in_array($name, $urlAttributes) && substr($attribute->value, 0, 7) !== 'http://')) {
# Found an unsafe attribute; remove it:
$element->removeAttribute($attribute->name);
$i--;
}
}
}
}
# Finally, return the safe HTML, minus the DOCTYPE, <html> and <body>:
$html = $dom->saveHTML();
$start = strpos($html, '<div>');
$end = strrpos($html, '</div>');
return substr($html, $start + 5, $end - $start - 5);
}
}
答案 2 :(得分:1)
我通常使用htmLawed lib,你可以使用它来过滤,保护&amp;清理HTML
http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/more.htm
答案 3 :(得分:0)
我认为strip_tags()功能与其名称相匹配。这都是透视问题。 :-)没有第二个参数,它会删除所有标签。第二个参数提供基本功能的例外。
您想要的似乎是strip_some_tags()
。
用正则表达式做什么呢?
function strip_some_tags($input, $taglist) {
$output=$input;
foreach ($taglist as $thistag) {
if (preg_match('/^[a-z]+$/i', $thistag)) {
$patterns=array(
'/' . "<".$thistag."\/?>" . '/',
'/' . "<\/".$thistag.">" . '/'
);
} else
if (preg_match('/^<[a-z]+>$/i', $thistag)) {
$patterns=array(
'/' . str_replace('>', "?>", $thistag) . '/',
'/' . str_replace('<', "<\/?", $thistag) . '/'
);
}
else {
$patterns=array();
}
$output=preg_replace($patterns, "", $output);
}
return $output;
}
$to_strip=array( "iframe", "script", "style", "embed", "object" );
$sampletext="Testing. <object>Am I an object?</object>\n";
print strip_some_tags($sampletext, $to_strip);
返回:
Testing. Am I an object?
当然,这只是剥离标签,而不是它们之间的东西。那是你要的吗?你没有在你的问题中指明。