如何逃脱内部CSS?

问题描述 投票:2回答:1

我想使用JavaScript将一些用户生成的CSS插入到我的html的head中。问题是当我转义某些字符时会破坏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的漏洞吗?

javascript css code-injection html-escape-characters
1个回答
0
投票

[我认为使用decodeURI()escape()之类的字眼几乎没有任何好处。

我建议先通过PostCSS之类的内容传递它,以便首先解析CSS。从安全性和功能性的角度来看,这具有多个好处。首先,它(应该)能够检测到任何语法错误,从而使您反抗代码注入。您依赖于PostCSS或所用解析器的安全性,但这总比没有好。将来也将使添加调试消息或CSS前缀等功能变得更加容易。

关于'更安全地注入未转义的CSS是否安全?'的具体问题:我将注意到,我的相对基础的调查似乎表明<style>元素似乎确实对脚本注入具有一定的保护作用,与其他标签相比最少。通常使用注入的代码(通过innerHTML),您可以通过执行something like this

注入一些代码
<img src="/" onerror = "alert(1);">

但是似乎对于样式标签来说,由于它的内容始终被认为是Text node,(实际上,在示例中,您明确地将其设置为文本节点)所以这似乎是不可能的。

无论如何,我仍然肯定会通过解析器传递它。 (如果找到通过样式标签执行JavaScript的任何方法,我将更新此答案)。

© www.soinside.com 2019 - 2024. All rights reserved.