Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / docs / templates / articles / contentSecurityPolicy.html
1 <h1>Content Security Policy (CSP)</h1>
2
3
4 <p>
5   In order to mitigate a large class of potential cross-site scripting issues,
6   Chrome's extension system has incorporated the general concept of
7   <a href="http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html">
8     <strong>Content Security Policy (CSP)</strong>
9   </a>. This introduces some fairly strict policies that will make extensions
10   more secure by default, and provides you with the ability to create and
11   enforce rules governing the types of content that can be loaded and executed
12   by your extensions and applications.
13 </p>
14
15 <p>
16   In general, CSP works as a black/whitelisting mechanism for resources loaded
17   or executed by your extensions. Defining a reasonable policy for your
18   extension enables you to carefully consider the resources that your extension
19   requires, and to ask the browser to ensure that those are the only resources
20   your extension has access to. These policies provide security over and above
21   the <a href="declare_permissions">host permissions</a> your extension
22   requests; they're an additional layer of protection, not a replacement.
23 </p>
24
25 <p>
26   On the web, such a policy is defined via an HTTP header or <code>meta</code>
27   element. Inside Chrome's extension system, neither is an appropriate
28   mechanism. Instead, an extension's policy is defined via the extension's
29   <a href="manifest"><code>manifest.json</code></a> file as follows:
30 </p>
31
32 <pre data-filename="manifest.json">
33 {
34   ...,
35   "content_security_policy": "[POLICY STRING GOES HERE]"
36   ...
37 }
38 </pre>
39
40 <p class="note">
41   For full details regarding CSP's syntax, please take a look at
42   <a href="http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#syntax">
43     the Content Security Policy specification
44   </a>, and the <a href="http://www.html5rocks.com/en/tutorials/security/content-security-policy/">
45     "An Introduction to Content Security Policy"
46   </a> article on HTML5Rocks.
47 </p>
48
49 <h2 id="restrictions">Default Policy Restrictions</h2>
50
51 <p>
52   Packages that do not define a <a href="manifestVersion">
53     <code>manifest_version</code>
54   </a> have no default content security policy. Those that select
55   <code>manifest_version</code> 2, have a default content security policy
56   of:
57 </p>
58
59 <pre>script-src 'self'; object-src 'self'</pre>
60
61 <p>
62   This policy adds security by limiting extensions and applications in three 
63   ways:
64 </p>
65
66 <h3 id="JSEval">Eval and related functions are disabled</h3>
67
68 <p>Code like the following does not work:</p>
69
70 <pre>
71 alert(eval("foo.bar.baz"));
72 window.setTimeout("alert('hi')", 10);
73 window.setInterval("alert('hi')", 10);
74 new Function("return foo.bar.baz");
75 </pre>
76
77 <p>Evaluating strings of JavaScript like this is a common XSS attack vector.
78 Instead, you should write code like:
79
80 <pre>
81 alert(foo && foo.bar && foo.bar.baz);
82 window.setTimeout(function() { alert('hi'); }, 10);
83 window.setInterval(function() { alert('hi'); }, 10);
84 function() { return foo && foo.bar && foo.bar.baz };
85 </pre>
86
87 <h3 id="JSExecution">Inline JavaScript will not be executed</h3>
88
89 <p>
90   Inline JavaScript will not be executed. This restriction bans both inline
91  <code>&lt;script&gt;</code> blocks <strong>and</strong> inline event handlers
92  (e.g. <code>&lt;button onclick="..."&gt;</code>).
93 </p>
94
95 <p>
96   The first restriction wipes out a huge class of cross-site scripting attacks
97   by making it impossible for you to accidentally execute script provided by a
98   malicious third-party. It does, however, require you to write your code with a
99   clean separation between content and behavior (which you should of course do
100   anyway, right?). An example might make this clearer. You might try to write a
101   <a href="browserAction#popups">Browser Action's popup</a> as a single
102   <code>popup.html</code> containing:
103 </p>
104
105 <pre data-filename="popup.html">
106 &lt;!doctype html&gt;
107 &lt;html&gt;
108   &lt;head&gt;
109     &lt;title&gt;My Awesome Popup!&lt;/title&gt;
110     &lt;script&gt;
111       function awesome() {
112         // do something awesome!
113       }
114
115       function totallyAwesome() {
116         // do something TOTALLY awesome!
117       }
118
119       function clickHandler(element) {
120         setTimeout(<strong>"awesome(); totallyAwesome()"</strong>, 1000);
121       }
122
123       function main() {
124         // Initialization work goes here.
125       }
126     &lt;/script&gt;
127   &lt;/head&gt;
128   &lt;body onload="main();"&gt;
129     &lt;button <strong>onclick="clickHandler(this)"</strong>&gt;
130       Click for awesomeness!
131     &lt;/button&gt;
132   &lt;/body&gt;
133 &lt;/html&gt;</pre>
134
135 <p>
136   Three things will need to change in order to make this work the way you expect
137   it to:
138 </p>
139
140 <ul>
141   <li>
142     The <code>clickHandler</code> definition needs to move into an external
143     JavaScript file (<code>popup.js</code> would be a good target).
144   </li>
145   <li>
146     <p>The inline event handler definitions must be rewritten in terms of
147     <code>addEventListener</code> and extracted into <code>popup.js</code>.</p>
148     <p>If you're currently kicking off your program's execution via code like
149     <code>&lt;body onload="main();"&gt;</code>, consider replacing it by hooking
150     into the document's <code>DOMContentLoaded</code> event, or the window's
151     <code>load</code> event, depending on your needs. Below we'll use the
152     former, as it generally triggers more quickly.</p>
153   </li>
154   <li>
155     The <code>setTimeout</code> call will need to be rewritten to avoid
156     converting the string <code>"awesome(); totallyAwesome()"</code> into
157     JavaScript for execution.
158   </li>
159 </ul>
160
161 <p>
162   Those changes might look something like the following:
163 </p>
164
165 <pre data-filename="popup.js">
166 function awesome() {
167   // Do something awesome!
168 }
169
170 function totallyAwesome() {
171   // do something TOTALLY awesome!
172 }
173
174 <strong>function awesomeTask() {
175   awesome();
176   totallyAwesome();
177 }</strong>
178
179 function clickHandler(e) {
180   setTimeout(<strong>awesomeTask</strong>, 1000);
181 }
182
183 function main() {
184   // Initialization work goes here.
185 }
186
187 // Add event listeners once the DOM has fully loaded by listening for the
188 // `DOMContentLoaded` event on the document, and adding your listeners to
189 // specific elements when it triggers.
190 <strong>document.addEventListener('DOMContentLoaded', function () {</strong>
191   document.querySelector('button').addEventListener('click', clickHandler);
192   main();
193 });
194 </pre>
195 <pre data-filename="popup.html">
196 &lt;!doctype html&gt;
197 &lt;html&gt;
198   &lt;head&gt;
199     &lt;title&gt;My Awesome Popup!&lt;/title&gt;
200     &lt;script <strong>src="popup.js"</strong>&gt;&lt;/script&gt;
201   &lt;/head&gt;
202   &lt;body&gt;
203     &lt;button&gt;Click for awesomeness!&lt;/button&gt;
204   &lt;/body&gt;
205 &lt;/html&gt;
206 </pre>
207
208 <p>
209
210
211 <h3 id="resourceLoading">Only local script and and object resources are loaded</h3>
212
213 <p>
214   Script and object resources can only be loaded from the extension's
215   package, not from the web at large. This ensures that your extension only
216   executes the code you've specifically approved, preventing an active network
217   attacker from maliciously redirecting your request for a resource.
218 </p>
219
220 <p>
221   Instead of writing code that depends on jQuery (or any other library) loading
222   from an external CDN, consider including the specific version of jQuery in
223   your extension package. That is, instead of:
224 </p>
225
226 <pre data-filename="popup.html">
227 &lt;!doctype html&gt;
228 &lt;html&gt;
229   &lt;head&gt;
230     &lt;title&gt;My Awesome Popup!&lt;/title&gt;
231     &lt;script src="<strong>http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js</strong>"&gt;&lt;/script&gt;
232   &lt;/head&gt;
233   &lt;body&gt;
234     &lt;button&gt;Click for awesomeness!&lt;/button&gt;
235   &lt;/body&gt;
236 &lt;/html&gt;
237 </pre>
238
239 <p>
240   Download the file, include it in your package, and write:
241 <p>
242
243 <pre data-filename="popup.html">
244 &lt;!doctype html&gt;
245 &lt;html&gt;
246   &lt;head&gt;
247     &lt;title&gt;My Awesome Popup!&lt;/title&gt;
248     &lt;script src="<strong>jquery.min.js</strong>"&gt;&lt;/script&gt;
249   &lt;/head&gt;
250   &lt;body&gt;
251     &lt;button&gt;Click for awesomeness!&lt;/button&gt;
252   &lt;/body&gt;
253 &lt;/html&gt;</pre>
254
255 <h2 id="relaxing">Relaxing the default policy</h2>
256
257 <h3 id="relaxing-inline-script">Inline Script</h3>
258
259 <p>
260   There is no mechanism for relaxing the restriction against executing inline
261   JavaScript. In particular, setting a script policy that includes
262   <code>'unsafe-inline'</code> will have no effect.
263 </p>
264
265 <h3 id="relaxing-remote-script">Remote Script</h3>
266
267 <p>
268   If you have a need for some external JavaScript or object
269   resources, you can relax the policy to a limited extent by whitelisting
270   secure origins from which scripts should be accepted. We want to ensure that
271   executable resources loaded with an extension's elevated permissions are
272   exactly the resources you expect, and haven't been replaced by an active
273   network attacker. As <a
274   href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack">man-in-the-middle
275   attacks</a> are both trivial and undetectable over HTTP, those origins will
276   not be accepted.
277 </p>
278
279 <p>
280   Currently, we allow whitelisting origins with the following schemes:
281   <code>blob</code>, <code>filesystem</code>, <code>https</code>,
282   <code>chrome-extension</code>, and <code>chrome-extension-resource</code>.
283   The host part of the origin must explicitly be specified for the
284   <code>https</code> and <code>chrome-extension</code> schemes.
285   Generic wildcards such as <code>https:</code>, <code>https://*</code> and
286   <code>https://*.com</code> are not allowed; subdomain wildcards such as
287   <code>https://*.example.com</code> are allowed.
288 </p>
289
290 <p>
291   To ease development, we're also allowing the whitelisting of resources loaded
292   over HTTP from servers on your local machine. You may whitelist script and
293   object sources on any port of either <code>http://127.0.0.1</code> or
294   <code>http://localhost</code>.
295 </p>
296
297 <p class="note">
298   The restriction against resources loaded over HTTP applies only to those
299   resources which are directly executed. You're still free, for example, to
300   make XMLHTTPRequest connections to any origin you like; the default policy
301   doesn't restrict <code>connect-src</code> or any of the other CSP directives
302   in any way.
303 </p>
304
305 <p>
306   A relaxed policy definition which allows script resources to be loaded from
307   <code>example.com</code> over HTTPS might look like:
308 </p>
309
310 <pre data-filename="manifest.json">
311 "content_security_policy": "script-src 'self' https://example.com; object-src 'self'"
312 </pre>
313
314 <p class="note">
315   Note that both <code>script-src</code> and <code>object-src</code> are defined
316   by the policy. Chrome will not accept a policy that doesn't limit each of
317   these values to (at least) <code>'self'</code>.
318 </p>
319
320 <p>
321   Making use of Google Analytics is the canonical example for this sort of
322   policy definition. It's common enough that we've provided an Analytics
323   boilerplate of sorts in the <a href="samples#event-tracking-with-google-analytics">Event Tracking
324   with Google Analytics</a> sample extension, and a
325 <a href="tut_analytics">brief tutorial</a> that goes into more detail.
326 </p>
327
328 <h3 id="relaxing-eval">Evaluated JavaScript</h3>
329
330 <p>
331   The policy against <code>eval()</code> and its relatives like
332   <code>setTimeout(String)</code>, <code>setInterval(String)</code>, and
333   <code>new Function(String)</code> can be relaxed by adding
334   <code>'unsafe-eval'</code> to your policy:
335 </p>
336
337 <pre data-filename="manifest.json">
338 "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
339 </pre>
340
341 <p>
342   However, we strongly recommend against doing this. These functions are
343   notorious XSS attack vectors.
344 </p>
345
346 <h2 id="tightening">Tightening the default policy</h2>
347
348 <p>
349   You may, of course, tighten this policy to whatever extent your extension
350   allows in order to increase security at the expense of convenience. To specify
351   that your extension can only load resources of <em>any</em> type (images, etc)
352   from its own package, for example, a policy of <code>default-src 'self'</code>
353   would be appropriate. The <a href="samples#mappy">Mappy</a> sample
354   extension is a good example of an extension that's been locked down above and
355   beyond the defaults.
356 </p>
357
358
359 <h2 id="interactions">Content Scripts</h2>
360
361 <p>
362   The policy that we have been discussing applies to the <a
363   href="background_pages">background pages</a> and <a href="event_pages">event
364   pages</a> of the extension. How they apply to the <a href="content_scripts">
365   content scripts</a> of the extension is more complicated.
366 </p>
367
368 <p>
369   Content scripts are generally not subject to the CSP of the extension. Since
370   content scripts are not HTML, the main impact of this is that they may use
371   <code>eval</code> even if the extension's CSP does not specify
372   <code>unsafe-eval</code>, although this is not recommended.  Additionally, the
373   CSP of the <em>page</em> does not apply to content scripts. More complicated
374   are <code>&lt;script&gt;</code> tags that content scripts create and put into
375   the DOM of the page they are running on. We will refer to these as DOM
376   injected scripts going forward.
377 </p>
378
379 <p>
380   DOM injected scripts that would be executed immediately upon injection into
381   the page will execute as you might expect. Imagine a content script with the
382   following code as a simple example:
383   <pre data-filename="content_script.js">
384     document.write("&lt;script&gt;alert(1);&lt;/script&gt;");
385   </pre>
386   This content script will cause an <code>alert</code> immediately upon the
387   <code>document.write()</code>. Note that this will execute regardless of the
388   policy a page may specify.
389 </p>
390
391 <p>
392   However, the behavior becomes more complicated both inside that DOM injected
393   script and for any script that does not immediately execute upon injection.
394   Imagine that our extension is running on a page that provides its own CSP
395   that specifies <code>script-src 'self'</code>. Now imagine the content script
396   executes the following code:
397   <pre data-filename="content_script.js">
398     document.write("&lt;button onclick='alert(1);'&gt;click me&lt;/button&gt;'");
399   </pre>
400   If a user clicks on that button, the <code>onclick</code> script will
401   <em>not</em> execute. This is because the script did not immediately execute
402   and code not interpreted until the click event occurs is not considered part
403   of the content script, so the CSP <em>of the page</em> (not of the extension)
404   restricts its behavior. And since that CSP does not specify
405   <code>unsafe-inline</code>, the inline event handler is blocked.
406 </p>
407
408 <p>
409   The correct way to implement the desired behavior in this case would be to add
410   the <code>onclick</code> handler as a function from the content script as
411   follows:
412   <pre data-filename="content_script.js">
413     document.write("&lt;button id='mybutton'&gt;click me&lt;/button&gt;'");
414     var button = document.getElementById('mybutton');
415     button.onclick = function() {
416       alert(1);
417     };
418   </pre>
419 </p>
420
421 <p>
422   Another similar issue arises if the content script executes the following:
423   <pre data-filename="content_script.js">
424     var script = document.createElement('script');
425     script.innerHTML = 'alert(1);'
426     document.getElementById('body').appendChild(script);
427   </pre>
428   In this case, the script <em>will</em> execute and the alert will pop up.
429   However, take this case:
430   <pre data-filename="content_script.js">
431     var script = document.createElement('script');
432     script.innerHTML = 'eval("alert(1);")';
433     document.getElementById('body').appendChild(script);
434   </pre>
435   While the initial script will execute, the call to <code>eval</code> will be
436   blocked. That is, while the initial script execution is allowed, the behavior
437   within the script will be regulated by the page's CSP.
438 </p>
439
440 <p>
441   Thus, depending on how you write DOM injected scripts in your extension,
442   changes to the page's CSP may affect the behavior of your extension. Since
443   content scripts are <em>not</em> affected by the page's CSP, this a great
444   reason to put as much behavior as possible of your extension into the content
445   script rather than DOM injected scripts.
446 </p>