Как избежать внутреннего CSS? - PullRequest
2 голосов
/ 01 октября 2019

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

Например:

    let css = `
        @import url('https://fonts.googleapis.com/css?family=Roboto&display=swap');
        body { font-family: "Roboto", sans-serif; }
        `,
        style = document.createElement('style');

    style.type = 'text/css';
    document.head.appendChild(style);
    css = escape(css);
    style.appendChild( document.createTextNode( css ) );

выводит:

    <style type="text/css" id="custom-theme-styles">
    @import url(&#39;https://fonts.googleapis.com/css?family=Roboto&amp;display=swap&#39;);
    body { font-family: &quot;Roboto&quot;, sans-serif !important; }
    </style>

Как видите, одинарные и двойные кавычки приводят к &#39; и &quot; соответственно. Амперсанд в строке запроса преобразуется в &amp;. Я также мог видеть проблемы с использованием дочернего комбинатора css (>).

Есть ли способ избежать css, чтобы он не ломался и не отображался безопасно? Это похоже на плохую идею, но если я не уйду от css, это даже проблема безопасности? Я могу ошибаться, но я не думаю, что тег <script> внутри тега <style> будет выполняться. Существуют ли какие-либо другие уязвимости, которые я пропускаю, так как не могу избежать css?

1 Ответ

3 голосов
/ 01 октября 2019

Я думаю, что использовать что-то вроде decodeURI() или escape() практически не имеет смысла.

Я бы рекомендовал пропустить его через что-то вроде PostCSS , чтобы сначала проанализировать CSS. Это имеет множество преимуществ как с точки зрения безопасности, так и с точки зрения функциональности. Во-первых, он (должен) быть в состоянии обнаружить любые синтаксические ошибки, которые, в свою очередь, защитят вас от внедрения кода. Вы полагаетесь на безопасность PostCSS или любого используемого вами парсера, но это лучше, чем ничего. Это также упростит добавление таких функций, как сообщения отладки или префиксы CSS, в будущем.

Для более конкретного вопроса 'безопасно ли вводить CSS без экранирования?' : я сделаюобратите внимание, что мое сравнительно простое исследование, похоже, предполагает, что элементы <style> в любом случае, похоже, имеют некоторую защиту от внедрения скрипта, по крайней мере, по сравнению с другими тегами. Обычно с внедренным кодом (через innerHTML) вы можете внедрить некоторый код, выполнив что-то вроде этого

<img src="/" onerror = "alert(1);">

Однако кажется, что для тега стиля, так как его содержимое всегда будет считаться Текстовый узел , (на самом деле вы явно задали его как текстовый узел в вашем примере), тогда это не то, что может показаться возможным.

Я бы все равно определенно пропустил его через парсер, чтобы быть уверенным. (Я обновлю этот ответ, если найду способ выполнения JavaScript с помощью тега стиля).

...