2

I am using CefSharp for off-screen rendering of web pages and I would like to execute a JavaScript code before taking a screenshot of the rendered page.

Using browser.EvaluateScriptAsync("document.body.scrollHeight") on some webpages (for example https://github.com/) unfortunately results in the following error:

Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src assets-cdn.github.com".

@ undefined:0:-1

This apparently happens because of the Content Security Policy header.

According to this answer, it is possible to disable the security in Firefox. Is it also possible to disable it in CEF? Or is it possible to execute scripts in any other way?

Community
  • 1
  • 1
TomsonTom
  • 742
  • 7
  • 22
  • You'll probably have to conduct your own research on this one, in theory you can modify the `headers` and modify the `CSP` (Removing them may also be an option). See http://magpcss.org/ceforum/viewtopic.php?f=6&t=10334&p=19338#p19338 – amaitland Jun 22 '16 at 21:45
  • You can also try some command line switches. http://peter.sh/experiments/chromium-command-line-switches/ CEF supports them too. – alexeibs Jun 23 '16 at 11:15
  • It's important to note that `CEF` only implements a subset of those command line switches. You'd have to check the source to see if a particular one was implemented. – amaitland Jun 23 '16 at 12:24
  • 1
    Did you find a solution to this? I'm still running into this issue. The weird thing is you can run `eval` on the console, so it should be possible to disable CSP for certain scripts. – Juan Feb 28 '19 at 14:10
  • Unfortunately I have never found a solution to this problem, I did not need to use it in the end. In case you solve the problem, feel free to post a solution and I will accept it for sure! – TomsonTom Mar 01 '19 at 11:22

2 Answers2

2

I just ran throught the same problem, using cefsharp to test some javascript code on websites I don't own. Recent cefsharp version refused to process such requests, using ExecuteJavascriptAsync().

I solved my problem the brutal way, using a proxy to disable the CSP check. The proxy replaces the meta tag http-equiv="content-security-policy" with a dummy one in order to disable it. Note that I didn't change the string length to avoid side effects such as changing "Content-Length" http headers.

The proxy: https://github.com/justcoding121/Titanium-Web-Proxy

Here you can find my quick and dirty code.

The code to start the proxy:

        var proxyServer = new ProxyServer();

        var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8123, true)
        {
        };

        // An explicit endpoint is where the client knows about the existence of a proxy
        // So client sends request in a proxy friendly manner
        proxyServer.AddEndPoint(explicitEndPoint);
        proxyServer.Start();

The proxyServer.BeforeResponse event:

    private async Task Proxy_BeforeResponse(object sender, Titanium.Web.Proxy.EventArguments.SessionEventArgs e)
    {

        if (e.HttpClient.Response.Headers.Headers.ContainsKey("Content-Type"))
        {
            if (e.HttpClient.Response.Headers.Headers["Content-Type"].Value.Contains("text/html"))
            {
                    string bodyString = await e.GetResponseBodyAsString();
                    e.SetResponseBodyString(bodyString.Replace("content-security-policy", "content-unsecure-policy"));
            }
        }
    }

The cefsharp switch to use the proxy:

cefSettings.CefCommandLineArgs.Add("proxy-server", "http://localhost:8123");
0

The CSP restrictions only apply if you evaluate your script, if you simply execute JavaScript then the restrictions don't apply. You can use ExecuteJavaScriptAsync. If you need to return a value, you can use GetMainFrame().ExecuteJavaScriptAsync("myregistredObject.retVal(document.body.scrollHeight)");

retVal must accept the appropriate type of either string or int.