2009-09-01 3 views
9

Vorformling Ich arbeite an einer Website und ich möchte einen Benutzer in der Lage, benutzerdefinierte CSS eingeben, die öffentlich angezeigt werden.Wie Whitelist-basierten CSS-Filter in PHP

Da jedoch eine ganze Reihe von XSS-Angriffen über CSS ausgeführt werden können, möchte ich in der Lage sein, einen Weg zu finden, die CSS-Ausgabe zu "säubern", ähnlich wie HTML Purifier durch Parsen des CSS läuft das geparste CSS gegen eine Whitelist und die Ausgabe eines neuen Stylesheets basierend auf dem geparsten CSS und der Whitelist.

Gibt es schon eine solche Bibliothek da draußen? Wenn nicht, gibt es eine CSS-Parsing-Bibliothek, die zum Erstellen einer benutzerdefinierten Implementierung verwendet werden kann?

+0

Ich weiß nicht, von einer solchen Bibliothek, sondern ein CSS-Parser sollte nicht so schwer sein zu implementieren. –

+1

CSS-Parsing ist nicht so einfach wie es aussieht, besonders wenn Sie bestimmte Konstrukte, die von schlechten Browser-Parsern falsch interpretiert werden können, ablehnen müssen. – bobince

+1

Black-Listing ist definitiv schwer, aber White-Listing ist nicht. Und ich sehe nicht, was beim Parsing von CSS so schwierig ist. Es ist keine Programmiersprache und Sie müssen in diesem speziellen Fall nicht etwas darauf basierend wiedergeben. Einige CSS-Konstrukte, die möglicherweise schwerer zu analysieren sind, sind @ -Regeln, aber Sie müssen nicht die vollständige CSS-Spezifikation unterstützen, sondern nur die in der weißen Liste enthaltene Teilmenge. –

Antwort

4

Ich denke, Sie gehen Ihren eigenen CSS-Parser und Filter zu schreiben, also hier, was ich als würde, obwohl ich noch nie so etwas getan haben:

  • eine (weiß) Liste der Stellen akzeptable CSS-Eigenschaften, die Ihre Benutzer verwenden können. Wie: color, font-family.
  • Ich glaube, es könnte besser sein, Kurzhandformen wie background zumindest am Anfang nicht zuzulassen, so dass Sie die Werte leicht analysieren können. Erfordert, dass sie explizit background-color, background-image schreiben.
  • Wenn Sie URLs möchten, lassen Sie nur relative URLs zu und verwerfen Sie alles, was nicht einmal annähernd wie eine URL aussieht. Protokollieren Sie diese Probleme trotzdem, damit Sie Ihren Parser und Validator verbessern können.
  • Seien Sie sehr strikt in Ihrer Analyse, verwerfen Sie alles, was Ihr Parser nicht versteht, auch wenn es gültiges CSS wäre. Mit anderen Worten, erstellen Sie Ihre eigene CSS-Teilmenge.

Beim Parsen wäre der schwierigste Teil das Parsen von complex CSS selectors. Aber Sie können hier auch Ihre eigene Teilmenge aufstellen.

Hier einige (Pseudo-) Code, vielleicht wird es Ihnen irgendwie helfen:

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