Как префикс CSS-фильтрации на основе белых списков в PHP

Я работаю над сайтом, и я хотел бы, чтобы пользователь мог ввести пользовательский CSS, который будет публично отображаться.

Однако, видя, что большое количество атак XSS можно предварительно сформировать с помощью CSS, я хотел бы найти способ «очистить» вывод CSS, подобно тому, как работает HTML-очиститель , путем разбора CSS, запуская анализируемый CSS против белого списка, а затем вывод новой таблицы стилей на основе проанализированного и белого списка CSS.

Есть ли там такая библиотека? Если нет, существует ли библиотека разбора CSS, которая может быть использована для создания пользовательской реализации?

Думаю, вы собираетесь написать свой собственный синтаксический анализатор и фильтр, поэтому я подумал, хотя я никогда не делал такого:

  • Создайте (белый) список допустимых свойств CSS, которые могут использовать ваши пользователи. Например: color , font-family .
  • Я считаю, что лучше не допускать коротких форм, таких как background , по крайней мере, в начале, чтобы вы могли легко анализировать значения. Требовать, чтобы они явно записывали background-color , background-image .
  • Если вам нужны URL-адреса, разрешите относительные URL-адреса и отбросьте все, что даже не похоже на URL-адрес. В любом случае, регистрируйте эти проблемы, чтобы улучшить свой синтаксический анализатор и валидатор.
  • Будьте очень строги в своем анализе, отбросьте все, что ваш парсер не понимает, даже если это будет действительный CSS. Другими словами, сделайте свой собственный подмножество CSS.

При разборе наиболее сложной частью будет синтаксический анализ сложных селекторов CSS . Но вы также можете наложить свой собственный подмножество.

Вот какой-то (псевдо) код, возможно, это поможет вам как-то:

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