拒绝应用内联样式,因为它违反了以下内容安全策略指令

Posted

技术标签:

【中文标题】拒绝应用内联样式,因为它违反了以下内容安全策略指令【英文标题】:Refused to apply inline style because it violates the following Content Security Policy directive 【发布时间】:2013-07-19 23:06:15 【问题描述】:

所以,大约 1 小时后,我的扩展程序就失败了。

我正在做我的扩展,它正在做我假装的事情。我做了一些更改,因为我不喜欢我删除了它们,现在我的扩展程序抛出错误:

拒绝应用内联样式,因为它违反了以下内容 内容安全策略指令:“default-src 'self'”。注意 'style-src' 没有明确设置,所以 'default-src' 被用作 后备。

是什么导致了这个错误?

我在以下方面进行了更改:

popup.html

<!DOCTYPE html>
<html ng-app="PinIt" ng-csp>
    <head>
        <link rel="stylesheet" href="css/popup.css">
        <script src="js/lib/jquery-1.8.2.min.js"></script>
        <script src="js/lib/angular.min.js"></script>
        <script src="js/app/app.js"></script>
        <script src="js/app/popup.js"></script> 
    </head>
    <body id="popup">
        <header>
            <h1>PinIt</h1>
        </header>
    <div ng-controller="PageController">
            <div>message</div>
            <h2>Page:</h2>
            <div id="elem">title</div>
            <div>url</div>
            <h2>Imagens:</h2>
            <ul>
                <li ng-repeat="pageInfo in pageInfos" style="list-style: none">
                    <div class="imgplusshare">
                    <img src=pageInfo class="imagemPopup"/>
                    <ul class="imas">
                      <li id="liFacebook" ng-click="fbshare(pageInfo)">
                      <span>
                      <img src="facebook_16.png"/>Facebook
                      </span>
                    </li>
                    <li id="liTwitter" ng-click="twshare(pageInfo)">
                    <span>
                    <img src="twitter-bird-16x16.png"/>Twitter
                    </span>
                    </li>
                    <li id="liGooglePlus" ng-click="gpshare(pageInfo)">
                    <span><img src="gplus-16.png"/>Google+</span>
                    </li>
                    <li id="liEmail" ng-click="mailshare(pageInfo)">
                    <span><img src="mail_icon_16.png"/>Email</span>
                    </li>
                    <hr>
                    </ul>

                    </div>
                    </li>

                    </ul>
</div>
    </body>
</html>

popup.js

  myApp.service('pageInfoService', function() 
        this.getInfo = function(callback) 
            var model = ;

            chrome.tabs.query('active': true,
            function (tabs) 
                if (tabs.length > 0)
                
                    model.title = tabs[0].title;
                    model.url = tabs[0].url;

                    chrome.tabs.sendMessage(tabs[0].id,  'action': 'PageInfo' , function (response) 

                        model.pageInfos = response;

                        callback(model);
                    );

                

            );
        ;
    );
    myApp.controller("PageController", function ($scope, pageInfoService) 

        pageInfoService.getInfo(function (info)            
            $scope.title = info.title;
            $scope.url = info.url;
            $scope.pageInfos = info.pageInfos;
            $scope.fbshare =  function($src) 
             chrome.windows.create(url:"http://www.facebook.com/sharer/sharer.php?u="+$src);
      ;    
            $scope.twshare =  function($src) 
             chrome.windows.create(url:"https://twitter.com/intent/tweet?url="+$src);
      ;
            $scope.gpshare =  function($src) 
             chrome.windows.create(url:"https://plus.google.com/share?url="+$src);
      ;
            $scope.mailshare =  function($src) 
             chrome.windows.create(url:"mailto:?subject=Imagem Partilhada por PinIt&body=<img src=\""+$src+"\"\\\>");
      ;



            $scope.$apply();


        );
    );

这是我的清单文件:


    "name": "PinIt",
    "version": "1.0",
    "manifest_version": 2,

    "description": "Pin It",
    "icons": 
        "128": "icon128.png"
    ,
    "browser_action": 
        "default_icon": "img/defaultIcon19x19.png",
        "default_popup": "popup.html",
        "default_title": "PinIt"
    ,
    "content_scripts": [ 
    "js": [ "js/lib/jquery-1.8.2.min.js", "js/app/content.js", "js/jquery-ui-1.10.3.custom.js" ],
    "matches": [ "*://*/*" ],
    "run_at": "document_start"
     ],
    "minimum_chrome_version": "18",
    "permissions": [ "http://*/*", "https://*/*", "unlimitedStorage", "contextMenus", "cookies", "tabs", "notifications" ],
    "content_security_policy": "default-src 'self'"

有什么建议吗?

【问题讨论】:

这是一个不同但相关的问题:***.com/questions/44495929/… 【参考方案1】:

正如错误消息所说,您有 CSP 禁止的内联样式。我在您的 HTML 中至少看到一个 (list-style: none)。而是将该样式放入您的 CSS 文件中。

为了进一步解释,内容安全政策不允许内联 CSS,因为它可能很危险。来自An Introduction to Content Security Policy:

"如果攻击者可以注入一个 直接包含一些恶意负载的脚本标签.. 浏览器没有机制来区分它和合法的 内联脚本标签。 CSP 通过禁止内联脚本解决了这个问题 完全:这是唯一的方法 当然。”

【讨论】:

这对我来说没有任何意义。对于内联scripts,我理解,但这个问题是关于内联styles。是否可以注入恶意的内联样式? 这是搜索的第一个结果[恶意内联样式]:dontkry.com/posts/code/disable-inline-styles.html 该页面上的参数似乎无效。它使用非内联样式的示例来演示您可能想要阻止内联样式的原因。它给出的例子确实是你可以用 CSS 做的坏事,但你为什么只阻止内联样式,而不是例如,所有的 CSS? @Trejkaz dontkry 页面上提到的样式内联样式。在这种情况下,“内联”包括&lt;style&gt; 元素,而不仅仅是style= 属性; -inline 意味着将link rel="Stylesheet" 元素放在head 中。关键是它是针对XSS 的安全防护,我们假设XSS 攻击者可以将任何内容添加到页面的body,但不能将link rel="Stylesheet" 添加到head 因为有人可以使用 css 将任何文本添加到您的网站。想想:":aftercontent:"You are hacked", fontSize:666【参考方案2】:

您还可以通过添加 style-src 'self' 'unsafe-inline'; 来放松 CSP 的样式

"content_security_policy": "default-src 'self' style-src 'self' 'unsafe-inline';" 

这将允许您在扩展程序中继续使用内联样式。

重要提示

正如其他人所指出的,这是推荐的,您应该将所有 CSS 放在一个专用文件中。请参阅OWASP explanation,了解为什么 CSS 可以成为攻击的载体(链接至 @KayakinKoder)。

【讨论】:

此建议对开发人员有利,但对用户不利。它为恶意软件编写者增加了一个额外的攻击向量。 CSP 使跨站点攻击变得更加困难。使用它,不要打败它! 我不得不对此投反对票,因为正如 sowbug 所说,允许 unsafe-inline 不利于安全性。 "If an attacker can inject a script tag that directly contains some malicious payload .. the browser has no mechanism by which to distinguish it from a legitimate inline script tag. CSP solves this problem by banning inline script entirely: it’s the only way to be sure." 我到处都看到过这种情况。到处都说“包含'不安全内联'很糟糕,但我还没有很好地解释为什么(特别是样式,而不是脚本),最好举个例子。 @JoshMc 我也有同样的问题,是的,内联样式是不安全的,就像内联脚本一样不安全。 OWASP 示例:owasp.org/index.php/… @KayakinKoder 不。不安全的风格甚至不像不安全的脚本那样不安全。没有现代浏览器会执行通过样式加载的js。【参考方案3】:

另一种方法是使用 CSSOM(CSS 对象模型),通过 DOM 节点上的 style 属性。

var myElem = document.querySelector('.my-selector');
myElem.style.color = 'blue';

更多关于 CSSOM 的细节: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.style

正如其他人所说,为 css 启用 unsafe-line 是解决此问题的另一种方法。

【讨论】:

【参考方案4】:

根据http://content-security-policy.com/ 最佳起点:

    default-src 'none'; 
    script-src 'self'; 
    connect-src 'self'; 
    img-src 'self'; 
    style-src 'self';
    font-src 'self';

切勿内联样式或脚本,因为它会破坏 CSP 的目的。您可以使用样式表设置样式属性,然后使用.js 文件中的函数来更改样式属性(如果需要)。

【讨论】:

【参考方案5】:

您可以在 Content-security-policy 中使用 add "img-src 'self' data:;" 并使用大纲 CSS。不要使用内联 CSS。它对攻击者是安全的。

【讨论】:

以上答案之一已经解决了这个问题。【参考方案6】:

好吧,我认为为时已晚,到目前为止,许多其他人都有解决方案。

但我希望这可以帮助:

我将 react 用于身份服务器,因此“不安全内联”根本不是一个选项。如果您查看控制台并实际阅读 CSP 文档,您可能会发现解决问题的方法有以下三种:

    如果您的项目使用 CSP,则“unsafe-inline”是不安全的,这是出于一个原因,它就像丢弃完整的策略一样,与根本没有 CSP 策略是一样的

      'sha-XXXCODE' 这很好,安全但不是最佳的,因为有很多手动工作,每次编译 SHA 可能会改变,所以很容易成为噩梦,只有在脚本或样式是不太可能改变,参考文献很少

      随机数。这是赢家!

Nonce 的工作方式与脚本类似

CSP 标头 ///csp 东西 nonce-12331

<script nonce="12331">
   //script content
</script>

由于csp中的nonce与标签相同,所以会执行脚本

对于内联样式,nonce 也以属性的形式出现,因此适用相同的规则。

所以生成随机数并将其放在你的内联脚本中

如果你使用 webpack,也许你使用的是 style-loader

下面的代码可以解决问题


module.exports = 
  module: 
    rules: [
      
        test: /\.css$/i,
        use: [
          
            loader: 'style-loader',
            options: 
              attributes: 
                nonce: '12345678',
              ,
            ,
          ,
          'css-loader',
        ],
      ,
    ],
  ,
;

【讨论】:

不,您不应该对 nonce 进行硬编码。这些应该为每次加载动态生成,否则它们就像根本没有 CSP 一样不安全。 关于如何为静态 SPA 的每次负载生成随机数的建议?

以上是关于拒绝应用内联样式,因为它违反了以下内容安全策略指令的主要内容,如果未能解决你的问题,请参考以下文章

Cordova Angular webView 错误拒绝应用内联样式,因为它违反了以下内容安全策略指令

拒绝执行内联脚本,因为它违反了以下内容安全策略指令:“script-src 'self'”

JQuery 3.5.1 并拒绝执行内联脚本,因为它违反了以下内容安全策略指令:

拒绝加载脚本,因为它违反了以下内容安全策略指令

Chrome 扩展“拒绝加载脚本,因为它违反了以下内容安全策略指令”

拒绝连接到“wss://live.mysite.com:3000/”,因为它违反了以下内容安全策略指令: