Sanitize User Entered CSS

时间:2012-06-01 作者:radiok

有人知道如何清理通过用户输入输入的CSS吗?我担心通过CSS编写跨站点脚本。我正在使用wp\\u filter\\u kses清理用户输入的HTML,但我需要一个类似于用户输入样式的解决方案。到目前为止,我正在使用以下丑陋且不完整的函数,但我希望得到更完整的函数。

function sanitizeCSS ( $css ) {
    $css = str_replace( \'/-moz-binding/\', \'\', $css );
    $css = str_replace( \'/expression/\', \'\', $css );
    $css = str_replace( \'/javascript/\', \'\', $css );
    $css = str_replace( \'/vbscript/\', \'\', $css );
    return $css; 
}

5 个回复
最合适的回答,由SO网友:radiok 整理而成

我发现最好的方法是将CSSTidy合并到我的插件中。我从JetPack中获取了一个页面,该页面具有自定义CSS功能。

JetPack的CSSTidy实现作为函数filter\\u attr包含在JetPack\\u Safe\\u CSS类中。我无法完全理解为什么JetPack在解析之前会将用户输入的CSS嵌套在一个“div”元素中,但经过一些尝试和错误后,我了解到CSSTidy并不能真正解析CSS文件。我从JetPack上撕下了代码。

我下载了CSSTidy,创建了一个包含CSSTidy PHP文件的目录。然后我要求上课。csstidy公司。php,并初始化一个新的csstidy对象。将要验证的CSS嵌套在“div”元素中,通过CSSTidy对其进行解析,然后将普通CSS从CSSTidy对象中拉出。到目前为止,已经安装了数千次(尽管我永远不知道有多少用户实际使用了我插件的CSS功能)。

我可能没有注意到这是我最初的问题,但我在寻找最简单、最简单的方法,而不是最技术、最复杂或最强大的方法。我重视尽可能少地修改WordPress体验。这就是为什么我把JetPack视为最接近“源头”的东西。我认为JetPack几乎是标准的,因为它是由Automatic(WordPress本身的开发人员)开发的。我唯一的。。。后悔CSSTidy在2007年被放弃了,所以我想我需要在某个时候找到另一个解决方案。

require_once( \'csstidy/class.csstidy.php\' );
$csstidy = new csstidy();
$csstidy->set_cfg( \'remove_bslash\', FALSE );
$csstidy->set_cfg( \'compress_colors\', FALSE );
$csstidy->set_cfg( \'compress_font-weight\', FALSE );
$csstidy->set_cfg( \'discard_invalid_properties\', TRUE );
$csstidy->set_cfg( \'merge_selectors\', FALSE );
$csstidy->set_cfg( \'remove_last_;\', FALSE );
$csstidy->set_cfg( \'css_level\', \'CSS3.0\' );
$csstovalidateindiv = \'div {\' . $csstovalidate . \'}\';
$csstovalidateindiv = preg_replace( \'/\\\\\\\\([0-9a-fA-F]{4})/\', \'\\\\\\\\\\\\\\\\$1\', $csstovalidateindiv );
$csstovalidateindiv = wp_kses_split( $csstovalidateindiv, array(), array() );
$csstidy->parse( $csstovalidateindiv );
$csstovalidateindiv = $csstidy->print->plain();
$csstovalidateindiv = str_replace( array( "\\n", "\\r", "\\t" ), \'\', $csstovalidateindiv );
preg_match( "/^div\\s*{(.*)}\\s*$/", $csstovalidateindiv, $matches );
if ( !empty( $matches[1] ) ) $cssvalidated = $matches[1];
(代码或未发生)

SO网友:fuxia

您需要一个真正的CSS解析器,如this one 过滤CSS。正则表达式或简单字符串替换不够安全。

SO网友:Ian Dunn

Jetpack并没有真正清理CSS,它只是清理了CSS,这有一个副作用,即删除一些漏洞,但不是全部。

攻击者仍然可以使用@import 导入未初始化的CSS;expression() 将XSS引入旧的IE浏览器;@charset 欺骗浏览器将CSS解释为HTML,从而打开XSS机会;使用任意协议设置URL以发起SSRF攻击等。

如果你想彻底消毒,你需要做如下的事情r2085-meta.

你应该对comprehensive test cases 验证它是否正在清理所有东西。

不过,CSSTidy并没有真正被抛弃;原作者之一forked the PHP class, 而Jetpack团队和其他人也做出了贡献,使其合理地保持最新。如果你觉得不舒服,Caja 是另一种选择。

SO网友:Nico

wp_filter_nohtml_kses()
似乎无法正常工作,因为它会转义“字符,因此您无法编写任何属性选择器。似乎没有“简单”的方法可以做到这一点。

SO网友:Chip Bennett

好吧,如果你想用50毫米口径的火炮,你可以使用wp_filter_nohtml_kses(), 但可能有更好的方法。

结束