Debugging CSP violation in Google Chrome

19,386

Solution 1

The cause of this problem is that TinyMCE creates some hidden iframe elements for its implementation of the editor. And TinyMCE implementation then tries to run JS using e.g. inline onclick attribute in one of those iframe elements, which obviously fails due CSP rules.

In general, if a script generates a new frame (e.g. about:blank) and then tries to run some code within it, Google Chrome cannot provide anything meaningful in Console nor to CSP resport URL. All you get is about:blank:1.

This is because Google Chrome doesn't keep info about the source for the inline onclick attribute. Basically the browser would need information about what code did the document.write() that added the misbehaving onclick code! I guess doing that for every document.write() would be too expensive for runtime performance. I wish they would keep track of the code location that created that specific iframe because that might help tracking the source of the problem. In addition, Google Chrome is unable to point you to the correct iframe when TinyMCE has created multiple invisible iframe elements because the URL of every one of those was about:blank before additional content was added via document.write().

Nowadays you can add 'report-sample' to the Content-Security-Policy which may help tracking down the problem a bit. Sometimes you can identify the problematic code from the script sample you get in the report.

Solution 2

Be sure to disable all Chrome Extensions when testing the CSP on your site - AdBlock and PhotoZoom extensions, for instance, both add their own inline styles to the DOM which trigger a violation (and subsequent hit to report-uri if you have that feature enabled, and others extensions likely do the same.

Solution 3

Although this question is old, the answer is still the same. The default code written by TinyMCE is not non-csp compliant.

Tinymce inserts inline css into the elements it adds the dom. It doesn't have to be this way, but it is the way they have written it. You can see it if you inspect the dom with with google or firefox dev tools, here is one example that can be found within the iframe it inserts:

<body spellcheck="false" id="tinymce" class="mce-content-body " onload="window.parent.tinymce.get('story_story').fire('load');" contenteditable="true"><p><br></p></body>

The browser detects this and raises a violation report as your csp does not allow this. There are two ways to make this error disappear:

1) add 'inline' or 'unsafe-inline' to your csp script-src for that page

or

2) recode the tinymce javascript files. This would require you to open all the javascript files are change the code it inserts to exclude the inline js parts. These scripts would then have to be placed into script files which are inserted into the dom to enable the code to still work.

Share:
19,386
Mikko Rantalainen
Author by

Mikko Rantalainen

My daily work is a closed source PHP project but I'm really interested in open source projects and I know PHP, C/C++, JavaScript and Perl 5 pretty well. I can do some Java, Python, x86 assembler (intel syntax) and some other programming languages, too. Purely functional languages such as Haskell are still a bit hard for me. I can do some linux kernel programming, too. I'm currently running Ubuntu (workstation, home computer, laptop) and LineageOS (phone) as my OS of choice. GPG: 563168EB

Updated on July 06, 2022

Comments

  • Mikko Rantalainen
    Mikko Rantalainen almost 2 years

    I'm trying to use TinyMCE while using following Content-Security-Policy HTTP header:

    X-WebKit-CSP: default-src 'self'; script-src 'self' 'unsafe-eval'; img-src *; media-src *; frame-src *; font-src *; style-src 'self' 'unsafe-inline'; report-uri /:reportcspviolation
    

    I get following errors in Tools - JavaScript Console:

    Refused to execute JavaScript URL because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval'".
     about:blank:1
    Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval'".
     test.xhtml:1
    Refused to execute JavaScript URL because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval'".
     about:blank:1
    Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval'".
     test.xhtml:1
    

    However, there's no executable JS code in the test.xhtml because it only uses external <script> to work with CSP header given. The reference to about:blank is also similarly invalid.

    Any ideas how to figure out where the cause for the CSP violation is?

    It seems that Chrome's internal JS debugger does not identify the source.

    In addition, for some reason, Chrome shows CSP violation reports as "Pending" in Tools - Developer Tools - Network but inspecting the data-to-be-send does not give any additional info. Example:

    {"csp-report":{"document-uri":"about:blank","referrer":"url-of/test.xhtml","violated-directive":"script-src 'self' 'unsafe-eval'","original-policy":"default-src 'self'; script-src 'self' 'unsafe-eval'; img-src *; media-src *; frame-src *; font-src *; style-src 'self' 'unsafe-inline'; report-uri /:reportcspviolation"}}
    

    I'm able to figure out that the error messages are about using e.g. onclick attribute in some piece of HTML that TinyMCE loads on the fly but what file to look for? Another error is probably a piece of TinyMCE HTML where some href has value that starts with javascript: but that too is really hard to find without any pointers from the Chrome. The whole setup works with Firefox 13 (using corresponding CSP header).

    Is there any way to make Chrome throw Exception for every CSP violation?

  • Mikko Rantalainen
    Mikko Rantalainen almost 12 years
    That's good info. Unfortunately it was not the cause for the problem I'm seeing. I get the same errors to console even with all Extensions disabled.
  • Mikko Rantalainen
    Mikko Rantalainen almost 12 years
    All the code (including the site, JS, XHTML, images, MathJax and TinyMCE) comes from the same domain. I've already found some locations where TinyMCE generates inline javascript (e.g. onclick attribute on some element) but locating all problematic source code by hand is really hard because TinyMCE generates code to be executed by the browser. Google Chrome says the resulting code is misbehaving but it does not say where, which is the whole problem.
  • Eraden
    Eraden almost 12 years
    Does this problem also occurs in other browsers (IE is not counted.) If so, can Firebug be more talkative? If you have a track toss it.
  • Mikko Rantalainen
    Mikko Rantalainen almost 12 years
    Firefox/Firebug does not catch this problem but I think it's because Firefox has bugs that cause CSP header to have no effect in some cases. In my experience, even plain Firefox with about:config setting security.csp.debug set to true is enough to identify all issues that Firefox is able to catch, Firebug is only a nicer frontend for the same data.
  • Andy Hayden
    Andy Hayden over 7 years
    It seems like this means CSP can't work if you want to use some chrome extensions e.g. bugherd... until they update to not unsafe-eval. :/
  • Andy Hayden
    Andy Hayden over 7 years
    This doesn't really answer the bolded question: "Is there any way to make Chrome to throw Exception for every CSP violation?" i.e. how the hell do you find out the cause of the the CSP violation. No line number is given.
  • ABrowne
    ABrowne over 7 years
    You are correct. As far as I know, the answer is No. I would love there to be an app that lists every line number of the violation across all doms (including ones loaded via iframes), however I am yet to find one.