3

I need some advice on how I can get my chrome manifest for an extension to allow a Google API talk between the servers and the application. The application loads fine when I point to it directly(not as extension).

However my problem is that when I load it as an extension I get the following error:

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 'self' https://apis.google.com/".

The application is built to interface with Google’s Calendar API.

This is what my HTML header looks like (locally):

<head>
    <link href='reset.css' rel="stylesheet" type="text/css">
     <link href='style.css' rel="stylesheet" type="text/css">
    <link href='animate-custom.css' rel="stylesheet" type="text/css">
     <script type="text/javascript" src="jquery.min.js"></script>
     <script src="https://apis.google.com/js/client.js?onload=onClientLoad" type="text/javascript"></script> 
    <script src="main.js" type="text/javascript"></script>
    <script type="text/javascript" src="moment_langs.js"></script>

    <title>Dashboard</title>
</head>

This is what it looks like when its loaded (**scripts loads - guessing an api call?):

<link href='reset.css' rel="stylesheet" type="text/css">
     <link href='style.css' rel="stylesheet" type="text/css">
    <link href='animate-custom.css' rel="stylesheet" type="text/css">
**<script src="https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.lm_l25KfNhA.O/m=client/rt=j/sv=1/d=1/ed=1/am=AQ/rs=AItRSTM1DJ5OrFPvETO8O24EqSIF_JCoKQ/cb=gapi.loaded_0" async=""></script>**
     <script type="text/javascript" src="jquery.min.js"></script>
     <script src="https://apis.google.com/js/client.js?onload=handleClientLoad" type="text/javascript"></script> 
    <script src="main.js" type="text/javascript"></script>
    <script type="text/javascript" src="moment_langs.js"></script>

My manifest:

{
  "manifest_version": 2,
  "name": "My Dashboard",
  "version": "1.2",
  "content_security_policy": "script-src 'self' https://apis.google.com/; object-src 'self'",
  "permissions": [
    "webRequest",
    "*://*.googleapis.com/*",
    "*://*.apis.google.com/*"
  ],


    "chrome_url_overrides" : {
    "newtab": "index.html"
  }
}
Devan
  • 35
  • 6
  • What is the problem ? What happens when you use it as an extension (in contrast to when using it as a web-app) ? How does it interface with Google Calendars API ? – gkalpak Nov 03 '13 at 08:24
  • @ExpertSystem I edited the question and stated the problem. The application pulls in calendar events and lists them. At this point, the calendar url is a hard coded public calendar. – Devan Nov 03 '13 at 08:42
  • I don't believe the jsapi library is supported for Chrome extensions. In my extension I call the Google APIs using XMLhttprequest directly. It's pretty straightforward. – pinoyyid Nov 03 '13 at 12:25
  • @pinoyyid could you expand on you solution ? This is all new to me. I understand what XMLhttprequest does however do I call this, "https://apis.google.com/js/client.js?onload=handleClientLoad" in the request ? – Devan Nov 05 '13 at 05:45
  • I don't use client.js at all. Instead call the underlying REST API directly from javascript. I've posted an answer with a code fragment – pinoyyid Nov 05 '13 at 06:17

2 Answers2

1

According to the docs regarding Content Security Policy configuration and more specificaly the policy against eval():

The policy against eval() and its relatives like setTimeout(String), setInterval(String), and new Function(String) can be relaxed by adding 'unsafe-eval' to your policy [...]

However, we strongly recommend against doing this. These functions are notorious XSS attack vectors.

(emphasis mine)

Thus, adding 'unsafe-eval' to your content-securty-policy might be a solution (but quite certainly not a good one in other aspects).

Pinoyyid's suggestion to use plain XMLHttpRequests could prove a better approach (if necessary setting the withcredentials attribute to true).

Community
  • 1
  • 1
gkalpak
  • 47,844
  • 8
  • 105
  • 118
  • good point but as you implied I am trying to avoid "unsafe-eval" since I am accessing users data hence don't want their information at risk. – Devan Nov 05 '13 at 05:48
  • oThere are ways to safely use **[eval() in a sandbox](http://developer.chrome.com/apps/sandboxingEval.html)** and pass data through `window.postMessage`. And again, there is the **XMLHttpRequest**. – gkalpak Nov 05 '13 at 06:15
  • I like the XMLHTTPRequest method however as noted below @pinoyyid comment I am not quite certain on how to implement it. – Devan Nov 05 '13 at 06:17
  • Try pinoyyid's answer (if you don't want to use a library, try using "raw" `XMLHttpRequest`). – gkalpak Nov 05 '13 at 06:30
1

Here is an example from my extension. In this case I'm calling the Drive 'trash' API.

            var xhr = new window['JSONHttpRequest']();

            xhr.open("POST", "https://www.googleapis.com/drive/v2/files/" + id + "/trash", true);
            xhr.setRequestHeader('Authorization', 'Bearer ' + token); // token comes from chrome.identity
            xhr.setRequestHeader('Content-Type', 'application/json');
            xhr.sendJSON(dmark);

Rather than the raw XMLHttpRequest, I use a JS library which creates a JSON wrapper around the XMLHttpRequest object.

pinoyyid
  • 21,499
  • 14
  • 64
  • 115
  • I am trying to implement raw XHMLhttpRequest. Can you see if this correct ? (http://jsfiddle.net/86YEu/) – Devan Nov 07 '13 at 05:03
  • I've updated your fiddle here http://jsfiddle.net/86YEu/ . There was a spurious = after the xhr.open. This version fails 403-Access not Configured which is likely down to the key not being valid, or not being registered to use the Calendar API. – pinoyyid Nov 07 '13 at 05:57