124

So, in about 1 hour my extensions failed hard.

I was doing my extension and it was doing what I pretended. I made some changes, and as I didnt liked I deleted them, and now my extension is throwing error:

Refused to apply inline style because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'style-src' was not explicitly set, so 'default-src' is used as a fallback.

What causes this error?

I made my changes in:

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();


  });
});

Here is my manifest file:

{
  "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'"
}

Any suggestion?

Alexander Nied
  • 12,804
  • 4
  • 25
  • 45
João Beirão
  • 1,431
  • 2
  • 9
  • 13
  • Here is a different but related issue: https://stackoverflow.com/questions/44495929/refused-to-apply-inline-style-because-it-violates-the-following-content-security – intrepidis Mar 12 '20 at 09:20

7 Answers7

133

You can also relax your CSP for styles by adding style-src 'self' 'unsafe-inline';

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

This will allow you to keep using inline style in your extension.

Important note

As others have pointed out, this is not recommended, and you should put all your CSS in a dedicated file. See the OWASP explanation on why CSS can be a vector for attacks (kudos to @ KayakinKoder for the link).

Michael T
  • 370
  • 4
  • 16
Métoule
  • 13,062
  • 2
  • 56
  • 84
  • 43
    This suggestion is good for developers but bad for users. It adds an additional attack vector for malware writers. CSP makes cross-site attacks much more difficult. Use it, don't defeat it! – sowbug Oct 31 '13 at 15:58
  • 6
    I have to downvote this because, as sowbug says, allowing unsafe-inline is bad for security. ["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."](http://www.html5rocks.com/en/tutorials/security/content-security-policy/#inline-code-considered-harmful) – culix Dec 30 '14 at 21:29
  • @culix: the relaxed CSP I suggested only concerns styles, and NOT scripts, since the default-src is 'self'. It's still unsafe, but the correct link would be http://scarybeastsecurity.blogspot.fr/2009/12/generic-cross-browser-cross-domain.html. – Métoule Jan 02 '15 at 13:14
  • 16
    I have seen this all over the place. Everywhere it says "Its bad to include 'unsafe-inline', but I am yet to have a good explanation as to why (specifically for style, not script), and preferably with an example. – Josh Mc Oct 14 '15 at 03:22
  • 9
    @JoshMc I had the same question, yes inline styles are unsafe, just as unsafe as inline script. OWASP example: https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.234_-_CSS_Escape_And_Strictly_Validate_Before_Inserting_Untrusted_Data_into_HTML_Style_Property_Values – KayakinKoder Feb 22 '17 at 08:44
  • 9
    @KayakinKoder No. Unsafe style isn't even close to as unsafe as unsafe scripts. No modern browsers will execute js loaded through style. – FINDarkside Oct 08 '18 at 11:18
  • injecting inline styles can be as dangerous as injecting scripts: https://www.owasp.org/index.php/Testing_for_CSS_Injection_(OTG-CLIENT-005) – Mladen B. Oct 29 '19 at 11:30
  • Should never allow inline. It bad for security. – Sovandara LENG Jun 15 '20 at 09:05
  • How is this the accepted answer? Stackoverflow? Hello? – Gal Silberman Dec 01 '22 at 08:10
29

As the error message says, you have an inline style, which CSP prohibits. I see at least one (list-style: none) in your HTML. Put that style in your CSS file instead.

To explain further, Content Security Policy does not allow inline CSS because it could be dangerous. From An Introduction to Content Security Policy:

"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."

Yves M.
  • 29,855
  • 23
  • 108
  • 144
sowbug
  • 4,644
  • 22
  • 29
  • 22
    This doesn't make any sense to me. For inline _scripts_ I understand it, but this question is about inline _styles_. Is it possible to inject a malicious inline style? – Andrew Schulman Jan 29 '16 at 16:47
  • 6
    This was the first result for the search [malicious inline style]: http://dontkry.com/posts/code/disable-inline-styles.html – sowbug Feb 01 '16 at 04:23
  • 3
    The argument on that page seems invalid. It uses examples of non-inline styles to demonstrate why you might want to block inline styles. The examples it gives are indeed evil things you could do with CSS, but why would you block only inline styles, instead of, for instance, all CSS? – Hakanai Jun 17 '16 at 02:24
  • I recommend asking that as a Stack Overflow question. The original questioner wanted to know why he was getting a certain error. Not that he ever plans to accept the answer given here, but that answer is correct (he's using a prohibited inline style). You're asking a different question. Ask it, rather than commenting. See http://meta.stackoverflow.com/questions/253836/ (you're not original questioner, but you're doing the same thing). – sowbug Jun 18 '16 at 04:24
  • 3
    @Trejkaz the styles mentioned on the dontkry page *are* inline styles. In this context, "inline" includes ` – Silas S. Brown Mar 06 '17 at 10:18
  • removed all inline styles but error is still there " because it violates the following Content Security Policy directive: "default-src 'none'". Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback." – Shalini Nov 22 '19 at 10:05
  • Does also means a inline script? If yes, I do not see any way of avoiding it in a framework like Angular. – Saurabh Tiwari Jan 28 '20 at 07:38
  • 2
    Because someone can add any text to your site with css. Think: ":after{content:"You are hacked", fontSize:666} – Ali Mert Çakar Sep 13 '20 at 22:17
11

As per http://content-security-policy.com/ The best place to start:

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

Never inline styles or scripts as it undermines the purpose of CSP. You can use a stylesheet to set a style property and then use a function in a .js file to change the style property (if need be).

Aurelio
  • 24,702
  • 9
  • 60
  • 63
5

Another method is to use the CSSOM (CSS Object Model), via the style property on a DOM node.

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

More details on CSSOM: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.style

As mentioned by others, enabling unsafe-line for css is another method to solve this.

sandstrom
  • 14,554
  • 7
  • 65
  • 62
3

Well, I think it is too late and many others have the solution so far.

But I hope this can Help:

I'm using react for an identity server so 'unsafe-inline' is not an option at all. If you look at your console and actually read the CSP docs, you might find that there are three options for solving the issue:

  1. 'unsafe-inline' as it says is unsafe if your project is using CSPs is for one reason and it is like throwing out the complete policy, will be the same to no have CSP policy at all

    1. 'sha-XXXCODE' this is good, safe but not optimal because there is a lot of manual work and every compilation the SHA might change so it will become easily a nightmare, use only when the script or style is unlikely to change and there are few references

    2. Nonce. This is the winner!

Nonce works in the similar way as scripts

CSP HEADER ///csp stuff nonce-12331

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

Because the nonce in the csp is the same that the tag, the script will be executed

In the case of inline styles, the nonce also came in the form of attribute so the same rules apply.

so generate the nonce and put it on your inline scritps

If you are using webpack maybe you are using the style-loader

the following code will do the trick


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

Juan Amador
  • 507
  • 4
  • 7
0

You can use in Content-security-policy add "img-src 'self' data:;" And Use outline CSS.Don't use Inline CSS.It's secure from attackers.

Anand Acharya
  • 89
  • 1
  • 3
0

If you have some content where you can't avoid inline css for example REST API response

or user input. then in that case I have created the solution for in the following blog. where you can separate html and css from each other and try to add the nonce value from the html meta tag header(which will be generate at the time of build)

CSP handling for inline css using nonce

  • 2
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/33869751) – Moritz Ringler Feb 21 '23 at 18:44