問題描述

有沒有人有任何想法如何清理透過使用者輸入輸入的 CSS?我關心透過 CSS 的 cross-site 指令碼。我正在使用 wp_filter_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; 
}

最佳解決方案

您將需要一個真正的 CSS 解析器,如 this one 來過濾 CSS 。正規表示式或簡單的字串替換不夠安全。

次佳解決方案

我發現最好的辦法是將 CSSTidy 納入我的外掛。我從 JetPack 獲取了一個自定義 CSS 功能的頁面。

JetPack 的 CSSTidy 實現包含在 Jetpack_Safe_CSS 類中作為函式 filter_attr 。我無法完全弄清楚為什麼 JetPack 在分析之前將使用者輸入的 CSS 嵌入到’div’ 元素中,但是在一些嘗試和錯誤之後,我發現 CSSTidy 並不能夠解析一個 CSS 檔案。這一課學到了我從 JetPack 中刪除了程式碼。

我下載了 CSSTidy,建立了一個目錄來包含 CSSTidy 的 PHP 檔案。然後我需要在我的程式碼中使用 class.csstidy.php,並初始化一個新的 csstidy 物件。將 CSS 巢狀在’div’ 元素中進行驗證,然後透過 CSSTidy 進行解析,然後將簡單的 CSS 從 csstidy 物件中退回。到目前為止,數以千計的安裝非常好 (儘管我永遠不會知道有多少使用者實際使用我的外掛的 CSS 功能) 。

我可能沒有注意到這是我的原始問題,但是我正在尋找最簡單,最簡單的方法,而不是最技術,最複雜或最強大的方法。我值得儘可能少地修改 WordPress 的體驗。這就是為什麼我把 JetPack 作為最接近”source” 的東西。我認為 JetPack 幾乎是由 Automattic(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( "/^divs*{(.*)}s*$/", $csstovalidateindiv, $matches );
if ( !empty( $matches[1] ) ) $cssvalidated = $matches[1];

(程式碼或沒有發生)

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。