2009-09-01 21 views
9

我正在一個網站上工作,我想讓用戶能夠輸入自定義CSS,並將其公開顯示。如何在PHP中預製基於白名單的CSS過濾

但是,通過CSS可以預見到很多XSS攻擊,我希望能夠通過解析CSS來運行,以「清理」CSS輸出,類似於HTML Purifier的工作方式,運行將解析的CSS與白名單進行對比,然後根據解析和列入白名單的CSS輸出新的樣式表。

這裏有一個這樣的圖書館嗎?如果沒有,是否有可用於創建自定義實現的CSS解析庫?

+0

我不知道任何這樣的庫,但一個CSS語法分析器不應該是很難實現的。 – 2009-09-01 20:35:59

+1

CSS解析並不像看起來那麼容易,尤其是當您不得不禁止某些可能被糟糕的瀏覽器解析器誤解的構造時。 – bobince 2009-09-01 23:20:55

+1

黑名單確實很難,但白名單不是。我不明白解析CSS有什麼困難。這不是一種編程語言,在這種情況下,您不需要基於它編寫某些東西。一些可能難以解析的CSS結構是@ -rules,但您不必支持完整的CSS規範,只需列出白名單。 – 2009-09-02 06:00:57

回答

4

我猜你會寫自己的CSS解析器和過濾器,所以這裏就是我會考慮,但我從來沒有做過這樣的事情:

  • 做的(白)名單您的用戶可以使用的可接受的CSS屬性。像:color,font-family
  • 我相信最好不要允許諸如background這樣的短手形式,至少在開始的時候,以便您可以輕鬆解析這些值。要求他們明確寫出background-color,background-image
  • 如果您需要URL,只允許使用相對URL,並丟棄所有甚至不像URL的內容。無論如何都要記錄這些問題,以便您可以改進解析器和驗證器。
  • 在解析過程中非常嚴格,放棄解析器不理解的所有內容,即使它是有效的CSS。換句話說,製作你自己的CSS子集。

解析時,最難的部分是complex CSS selectors的解析。但是你也可以在這裏強加你自己的子集。

這裏的一些(僞)代碼,也許它會幫助你以某種方式:

<?php 

function tokenizeCSS() { 
    return array(
     array(
      'selector' => '#foo .bar', 
      'properties' => array(
       'background-color' => 'transparent', 
       'color'   => '#fff', 
      ), 
     ); 
    ); 
} 

function colorValidator($color) 
{} 

/** 
* This is basically the white list. Keys are accepted CSS properties 
* and values are the validator callbacks. 
*/ 
$propertyValidators = array(
    'background-color' => 'colorValidator', 
    'color'   => 'colorValidator', 
); 

$filteredRules = array(); 

foreach (tokenizeCSS() as $rule) { 
    if (! validSelector($rule['selector'])) { 
     continue; 
    } 

    foreach ($rule['properties'] as $property => $value) { 
     /** 
     * Check property is in white list 
     */ 
     if (! isset($propertyValidators[$property]) { 
      continue; 
     } 

     /** 
     * Check property is valid 
     */ 
     if (! $propertyValidators[$property]($value)) { 
      continue; 
     } 

     /** 
     * Valid rule 
     */ 
     $filteredRules[$rule['selector']][$property] = $value; 
    } 
}