2009-09-01 21 views
9

Estoy trabajando en un sitio y me gustaría que un usuario pueda ingresar un CSS personalizado que se mostrará públicamente.Cómo preformar el filtrado de CSS basado en listas blancas en PHP

Sin embargo, dado que una gran cantidad de ataques XSS se pueden realizar a través de CSS, me gustaría poder encontrar una forma de "limpiar" la salida de CSS, similar a cómo funciona HTML Purifier, al analizar el CSS, ejecutándose el CSS analizado contra una lista blanca y, a continuación, la salida de una nueva hoja de estilo basada en el CSS analizado y en la lista blanca.

¿Ya hay una biblioteca como esta? Si no, ¿hay una biblioteca de análisis de CSS que pueda usarse para crear una implementación personalizada?

+0

no sé de dicha biblioteca, pero un analizador CSS no debería ser tan difícil de implementar. –

+1

El análisis de CSS no es tan fácil como parece, especialmente cuando tiene que rechazar ciertas construcciones que pueden ser malinterpretadas por analizadores de navegador incorrectos. – bobince

+1

Lista negra es definitivamente difícil, pero la lista blanca no lo es. Y no veo qué es tan difícil sobre el análisis de CSS. No es un lenguaje de programación y no necesita renderizar algo basado en él, en este caso particular. Algunas construcciones CSS que pueden ser más difíciles de analizar son reglas @, pero no es necesario que admita la especificación CSS completa, solo el subconjunto en la lista blanca. –

Respuesta

4

Creo que se va a escribir su propio analizador CSS y el filtro, por lo que aquí es lo que yo considero, aunque nunca he hecho tal cosa:

  • Haga una lista (blanco) de propiedades de CSS aceptables que sus usuarios pueden usar. Me gusta: color, font-family.
  • Creo que sería mejor no permitir formas abreviadas como background, al menos al principio, para que pueda analizar fácilmente los valores. Requerir que escriban explícitamente background-color, background-image.
  • Si desea URL, solo permita URL relativas, y descarte todo lo que ni siquiera se ve como una URL. Registre estos problemas de todos modos, para que pueda mejorar su analizador y validador.
  • Sea muy estricto en su análisis sintáctico, deseche todo lo que su analizador no comprenda, incluso si fuera un CSS válido. En otras palabras, crea tu propio subconjunto de CSS.

Al analizar, la parte más difícil sería el análisis de complex CSS selectors. Pero puede imponer su propio subconjunto aquí también.

Aquí hay algo de código (pseudo), tal vez le ayudará de alguna manera:

<?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; 
    } 
} 
Cuestiones relacionadas