51

I am using an external JavaScript lib in my chrome extension. I has inline execution, so I get following kind of error

(The error I get on console)

Refused to execute JavaScript URL because it violates the following Content Security Policy directive: "script-src 'self' chrome-extension://". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.

The error message clearly says there is a work-around possible.

Chrome-Content Security Policy says not possible. Many related question cited this link.

Blog This blogger says it is possible, but probably this is applicable to only older chrome extension.

Any work around possible?

PS: don't wanna/can't change the entire library I am using.

EDIT: how to use hash or nonce to enable inline execution.

3
  • Similar questions have been asked, but I guess something has been missed. Commented Sep 2, 2014 at 14:06
  • please give us the code creating the error Commented Sep 2, 2014 at 14:25
  • I think since manifest 3 this has no workaround Commented Dec 14, 2021 at 20:34

5 Answers 5

31

No, this is not possible to relax this policy. unsafe-inline is specifically ignored by Chrome Extensions since manifest version 2.

Documentation (emphasis mine):

There is no mechanism for relaxing the restriction against executing inline JavaScript. In particular, setting a script policy that includes 'unsafe-inline' will have no effect.

The error message mentions several possible ways, but the docs are clear that no CSP will allow inline scripting, and ignoring unsafe-inline is but one of the measures.

Update

As of Chrome 46, inline scripts can be whitelisted by specifying the base64-encoded hash of the source code in the policy. This hash must be prefixed by the used hash algorithm (sha256, sha384 or sha512). See Hash usage for elements for an example.

See this answer for more in-depth look at whitelisting.

Sign up to request clarification or add additional context in comments.

6 Comments

+1; to clarify for the OP: the CSP specification allows this restriction to be relaxed (hence the suggestion to add unsafe-eval), but what Chrome extensions allow in a CSP is narrower than the general CSP spec.
@Xan - agree to 'unsafe-inline' will have not effect. But I believe there are still other ways - hash/nonce, as pointed out by error message.
@AmitG If you insist on disagreeing with documentation, it's your choice.
This answer no longer applies, see my answer with the updated state here.
@ChrisHunt Thanks for the updated answer on this, I included new information in my answer.
|
22

Copied from my answer to a similar question here. For recent versions of Chrome (46+) the current answer is no longer true. unsafe-inline still has no effect (in both the manifest and in meta header tags), but per the documentation, you can use the technique described here to relax the restriction.

Hash usage for <script> elements

The script-src directive lets developers whitelist a particular inline script by specifying its hash as an allowed source of script.

Usage is straightforward. The server computes the hash of a particular script block’s contents, and includes the base64 encoding of that value in the Content-Security-Policy header:

Content-Security-Policy: default-src 'self';
                     script-src 'self' https://example.com 'sha256-base64 encoded hash'

As an example, consider:

manifest.json:

{
  "manifest_version": 2,
  "name": "csp test",
  "version": "1.0.0",
  "minimum_chrome_version": "46",
  "content_security_policy": "script-src 'self' 'sha256-WOdSzz11/3cpqOdrm89LBL2UPwEU9EhbDtMy2OciEhs='",
  "background": {
    "page": "background.html"
  }
}

background.html:

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <script>alert('foo');</script>
  </body>
</html>

Result:
alert dialog from inline script

I also tested putting the applicable directive in a meta tag instead of the manifest. While the CSP indicated in the console message did include the content of the tag, it would not execute the inline script (in Chrome 53).

new background.html:

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'sha256-WOdSzz11/3cpqOdrm89LBL2UPwEU9EhbDtMy2OciEhs='">
  </head>
  <body>
    <script>alert('foo');</script>
  </body>
</html>

Result:
console error messages about content security policy

4 Comments

What about executing JS inline with a anchor href like <a href="javascript:void(0)">Hello</a>. I've tried rRMdkshZyJlCmDX27XnL7g3zXaxv7ei6Sg+yt4R3svU= and 97l24HYIWEdSIQ8PoMHzpxiGCZuyBDXtN19RPKFsOgk= with no luck.
the solution using manifest.json worked for me; the meta tag version did not work.
I get a 'content_security_policy': Ignored insecure CSP value "sha256-TTV2e1hDY8O7+uUJbANScTuJ3ibjGZ9SqN6LdxfzDCs=" in directive 'script-src'.
while trying to load the extension it says "Insecure CSP,Could not load manifest"
6

nonce is specifically ignored by Chrome Extensions as unsafe. As of Sep 2020 (v.85) only the 'sha256..' option works. But is inconvenient since the hash changes with every html file update.

1 Comment

can you show an example with sha256 I get that it's invalid as well with this.
2

I've got this problem after I added a simple checkbox on the login page to toggle password visibility and here is how I have fixed my problem, hope it helps;

  • I've stopped using my checkbox's onclick event, which was causing this problem in incognito mode of chrome and instead gave an id to my checkbox.

Before

<div class="form__row">
        <div class="form__controls">
            <label class="checkbox"><input type="checkbox" onclick="togglePasswordVisibility()"> Show password</label>
        </div>
    </div>

After

<div class="form__row">
        <div class="form__controls">
            <label class="checkbox"><input type="checkbox" id="checkboxTogglePasswordVisibility"> Show password</label>
        </div>
    </div>
  • I've created a Script.js file and added an event listener method into it to handle onclick event of my checkbox to do the job.

Remember to reference your js file, if you haven't, yet. You can simply reference it like this.

<script src="../Scripts/Script.js"></script>

And here is the event listener that I've added into my Script.js.

$(document).ready(function () {
    addEventListenerForCheckboxTogglePasswordVisibility()
});

function addEventListenerForCheckboxTogglePasswordVisibility() {
    var checkbox = document.getElementById("checkboxTogglePasswordVisibility");
    if (checkbox !== null) {
        checkbox.addEventListener('click', togglePasswordVisibility);
    }
}

function togglePasswordVisibility() {
    var passwordElement = document.getElementById("password");
    if (passwordElement.type === "password") {
        passwordElement.type = "text";
    } else {
        passwordElement.type = "password";
    }
}

Error before the fix;

enter image description here

Comments

1

You can config the csp nonce like this


Content-Security-Policy: script-src 'nonce-xyz123'; style-src 'nonce-xyz123';


<script src="https://www.paypal.com/sdk/js?client-id=sb" data-csp-nonce="xyz-123">

https://developer.paypal.com/docs/checkout/troubleshoot/support/#mobile

4 Comments

when I try this every other .js file in my manifest refuses to load because it violates this policy
agreed this doesn't work for me either... same thing violates the policy
Do you have an example of this working with the paypal sdk currently?
Hi @JosephAstrahan, I'm no longer work on this project. May be the rule was changed

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.