我有用户提交一些文本(包括随机html图像链接),然后我试图创建一个基本的BBCode [img][/img]标签在文本中的图像。
我目前测试的方式是这样的:
字符串(取自随机论坛):
After a fair few years of doing the usual lowering, fitting wheels etc,when it comes to car modifying, we spent a couple of years doing Minimoto racing all round the country in the Southern British Minimoto Championship winning the 2006 Production Privateer Championship.<br />
<br />
<img src="http://i2.photobucket.com/albums/y18/moo0484/scan0001.jpg" border="0" class="tcattdimglink" onload="NcodeImageResizer.createOn(this);" alt="" /><br />
<br />
<img src="http://i2.photobucket.com/albums/y18/moo0484/01072007065.jpg" border="0" class="tcattdimglink" onload="NcodeImageResizer.createOn(this);" alt="" /><br />
然后我替换任何图像属性/改变图像标签为bbcode使用一个函数:
function convert($text) {
$text = preg_replace('/class=".*?"/', '', $text);
$text = preg_replace('/alt=".*?"/', '', $text);
$text = preg_replace('/src="/', '', $text);
$text = preg_replace('/border=".*?"/', '', $text);
$text = preg_replace('/onload=".*?"/', '', $text);
$text = str_replace("<img", "[img]", "$text");
$text = str_replace('">', "[/img]", "$text");
return nl2br($text);
}
如果标签没有以斜杠结束,这可以很好地工作。我可以添加另一条规则:
$text = str_replace('"/>', "[/img]", "$text");
这将工作,但仍然有空白空间,从我删除的属性。
所以我的问题是,我可以从img标签之间删除空白:
<img />
例如,在preg_replace函数中,.*?替换"之间的内容。
我可以做一个类似的事情,但与img标签,并删除他们之间的空白?
我显然不能直接跑:
$text = preg_replace('/'s+/', '', $text);
因为我需要文本中的空白等
谢谢!
你应该删除任何空白和胭脂属性,所以几乎所有的属性,特别是on* Event属性,如onClick,onBlur。在HTML中添加XSS攻击的方法太多了。如果你想让用户输入HTML,可以使用htmlpurifier。它很容易在你的代码中初始化,并且有很多选项。
一种简单的替代方法是提取img的src,然后删除属性并将src放回并制作图像字符串,然后使用strip_tags()删除所有HTML,然后将图像连接到文本上。但是它缺少图像的定位。
所以像
<?php
$html = <<<DEMO
After a fair <script>alert('XSS');</script>few ...
winning the 2006 Production Privateer Championship.<br />
<div style="background-image: url(javascript:alert('XSS'))"></div>
<br />
<img src="http://i2.photobucket.com/albums/y18/moo0484/scan0001.jpg" border="0" class="tcattdimglink" onload="NcodeImageResizer.createOn(this);" alt="" /><br />
<br />
text here
<img src="http://i2.photobucket.com/albums/y18/moo0484/01072007065.jpg" border="0" class="tcattdimglink" onload="NcodeImageResizer.createOn(this);" alt="" /><br />
more txt here
DEMO;
$dom = new DOMDocument;
@$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
if (false === ($elements = $xpath->query("//*"))) die('Error');
foreach ($elements as $element) {
//remove script tags
if($element->nodeName=='script'){
$element->parentNode->removeChild($element);
}
//remove empty tags but not images
if (!$element->hasChildNodes() || $element->nodeValue == '') {
if($element->nodeName != 'img'){
$element->parentNode->removeChild($element);
}
}
//remove all attributes except links and imgs
for ($i = $element->attributes->length; --$i >= 0;) {
$name = $element->attributes->item($i)->name;
if (('img' === $element->nodeName && 'src' === $name) || ('a' === $element->nodeName && 'href' === $name)){
continue;
}
$element->removeAttribute($name);
}
}
//put dom together and remove the document body
echo preg_replace('~<(?:!DOCTYPE|/?(?:html|body))[^>]*>'s*~i', '', $dom->saveHTML());
/*
<p>After a fair few ...
winning the 2006 Production Privateer Championship.</p>
<img src="http://i2.photobucket.com/albums/y18/moo0484/scan0001.jpg">
text here
<img src="http://i2.photobucket.com/albums/y18/moo0484/01072007065.jpg">
more txt here
*/
虽然只是考虑使用html净化器,但90年代也在调用他们想要的BBCODE,而不是使用markdown。; p
好运