2009-09-01 2 views
9

Sto lavorando su un sito e vorrei rendere un utente in grado di inserire CSS personalizzati in modo che vengano visualizzati pubblicamente.Come preformare il filtro CSS basato su whitelist in PHP

Tuttavia, visto che una buona parte degli attacchi XSS può essere preformata tramite CSS, mi piacerebbe essere in grado di trovare un modo per "pulire" l'output CSS, analogamente a come funziona HTML Purifier, analizzando il CSS, in esecuzione il CSS analizzato contro una whitelist, e quindi l'output di un nuovo foglio di stile basato sul CSS con parser e whitelist.

Esiste già una biblioteca come questa? In caso contrario, esiste una libreria di analisi CSS che può essere utilizzata per creare un'implementazione personalizzata?

+0

non so di qualsiasi libreria, ma un parser CSS non dovrebbe essere così difficile da attuare. –

+1

L'analisi CSS non è così semplice come sembra, specialmente quando devi disabilitare determinati costrutti che possono essere interpretati erroneamente dai parser del browser. – bobince

+1

L'elenco in nero è decisamente difficile, ma l'elenco in bianco non lo è. E non vedo cosa ci sia di tanto difficile analizzare i CSS. Non è un linguaggio di programmazione e in questo caso particolare non è necessario eseguire il rendering di qualcosa basato su di esso. Alcuni costrutti CSS che possono essere più difficili da analizzare sono @ -rules, ma non devi supportare le specifiche CSS complete, ma solo il sottoinsieme in white list. –

risposta

4

immagino che stai andando a scrivere il proprio parser CSS e filtro, quindi ecco quello che avevo in considerazione, anche se non ho mai fatto una cosa del genere:

  • Fai un (bianco) elenco delle proprietà CSS accettabili che gli utenti possono utilizzare. Come: color, font-family.
  • Credo che potrebbe essere meglio non consentire forme a mano corta come background, almeno all'inizio, in modo da poter facilmente analizzare i valori. Richiedere che scrivano esplicitamente background-color, background-image.
  • Se desideri URL, consenti solo URL relativi e scarta tutto ciò che non sembra nemmeno un URL. Registra comunque questi problemi, in modo da poter migliorare il parser e il validatore.
  • Sii molto severo nel tuo parsing, scarta tutto ciò che il tuo parser non capisce anche se sarebbe un CSS valido. In altre parole, crea il tuo sottoinsieme CSS.

Durante l'analisi, la parte più difficile sarebbe il parsing di complex CSS selectors. Ma puoi anche imporre il tuo sottoinsieme.

Ecco po 'di codice (pseudo), forse vi aiuterà in qualche modo:

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