Я хочу, чтобы пользователи могли использовать свои собственные таблицы стилей для профилей thei на моем форуме, но я боюсь возможных уязвимостей безопасности. Есть ли у кого-нибудь советы по санированию CSS?
Основной процесс: пользователь вводит CSS в форму -> Сохранить в DB -> Вывод как встроенный CSS
HTMLPurifier с CSSTidy делает то, что вы ищете.
HTMLPurifier в первую очередь предназначен для дезинфекции HTML, но также имеет возможность извлекать блоки стиля с помощью CSSTidy.
В документах HTMLPurifier есть пример (но, увы, я использовал две ссылки на сообщение).
Вот еще один:
require_once './htmlpurifier/library/HTMLPurifier.auto.php'; require_once './csstidy/class.csstidy.php'; // define some css $input_css = " body { margin: 0px; padding: 0px; /* JS injection */ background-image: url(javascript:alert('Injected')); } a { color: #ccc; text-decoration: none; /* dangerous proprietary IE attribute */ behavior:url(hilite.htc); /* dangerous proprietary FF attribute */ -moz-binding: url('http://virus.com/htmlBindings.xml'); } .banner { /* absolute position can be used for phishing */ position: absolute; top: 0px; left: 0px; } "; // Create a new configuration object $config = HTMLPurifier_Config::createDefault(); $config->set('Filter.ExtractStyleBlocks', TRUE); // Create a new purifier instance $purifier = new HTMLPurifier($config); // Turn off strict warnings (CSSTidy throws some warnings on PHP 5.2+) $level = error_reporting(E_ALL & ~E_STRICT); // Wrap our CSS in style tags and pass to purifier. // we're not actually interested in the html response though $html = $purifier->purify('<style>'.$input_css.'</style>'); // Revert error reporting error_reporting($level); // The "style" blocks are stored seperately $output_css = $purifier->context->get('StyleBlocks'); // Get the first style block echo $output_css[0];
И выход:
body { margin:0; padding:0; } a { color:#ccc; text-decoration:none; } .banner { }
Определите сами классы и создайте графический интерфейс для применения цветов и других свойств к каждому классу, используйте тот же подход, который твиттер делает для этого.
alt text http://img.ruphp.com/php/3217158e9c48538eb127fb1678dab6ae.png
Конечно, это будет работать, только если ваш макет фиксирован и определен администратором, а не пользователем.
Я не вижу, как это может создать уязвимости безопасности, если только профили не используются совместно с другими пользователями.
Если они разделены, могут возникнуть уязвимости CSRF (поскольку CSS может генерировать запросы GET для включения изображений, шрифтов, других таблиц стилей и т. Д.). Они также могут использовать content
чтобы обмануть пользователей, щелкнув некоторые места, скрыть важную функциональность и т. Д. И, конечно же, вам нужно было бы избежать <
, >
и, возможно, &
чтобы предотвратить XSS (если CSS встроен в HTML).
Что касается библиотек для санитарии, я не знаю ни одного (возможно, опрятного).