Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: chrome/common/extensions/docs/server2/templates/articles/contentSecurityPolicy.html

Issue 10832042: Extensions Docs Server: Doc conversion script (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: everything but svn stuff Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 <h1>Content Security Policy (CSP)</h1>
2
3
4 <p>
5 In order to mitigate a large class of potental 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-specif ication.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="manifest.html#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.html"><code>manifest.json</code></a> file as follows:
30 </p>
31
32 <pre>{
33 ...,
34 "content_security_policy": "[POLICY STRING GOES HERE]"
35 ...
36 }</pre>
37
38 <p class="note">
39 For full details regarding CSP's syntax, please take a look at
40 <a href="http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specif ication.dev.html#syntax">
41 the Content Security Policy specification
42 </a>.
43 </p>
44
45 <h2>Default Policy Restrictions</h2>
46
47 <p>
48 Packages that do not define a <a href="manifestVersion.html">
49 <code>manifest_version</code>
50 </a> have no default content security policy. Those that select
51 <code>manifest_version</code></a> 2, have a default content security policy
52 of:
53 </p>
54
55 <pre>script-src 'self'; object-src 'self'</pre>
56
57 <p>
58 This policy adds security by limiting extensions and applications in two ways:
59 </p>
60
61 <h3>Inline JavaScript will not be executed</h3>
62
63 <p>
64 Inline JavaScript, as well as dangerous string-to-JavaScript methods like
65 <code>eval</code>, will not be executed. This restriction bans both inline
66 <code>&lt;script&gt;</code> blocks <strong>and</strong> inline event handlers
67 (e.g. <code>&lt;button onclick="..."&gt;</code>).
68 </p>
69
70 <p>
71 The first restriction wipes out a huge class of cross-site scripting attacks
72 by making it impossible for you to accidentally execute script provided by a
73 malicious third-party. It does, however, require you to write your code with a
74 clean separation between content and behavior (which you should of course do
75 anyway, right?). An example might make this clearer. You might try to write a
76 <a href="browserAction.html#popups">Browser Action's popup</a> as a single
77 <code>popup.html</code> containing:
78 </p>
79
80 <pre>&lt;!doctype html&gt;
81 &lt;html&gt;
82 &lt;head&gt;
83 &lt;title&gt;My Awesome Popup!&lt;/title&gt;
84 &lt;script&gt;
85 function awesome() {
86 // do something awesome!
87 }
88
89 function totallyAwesome() {
90 // do something TOTALLY awesome!
91 }
92
93 function clickHandler(element) {
94 setTimeout(<strong>"awesome(); totallyAwesome()"</strong>, 1000);
95 }
96 &lt;/script&gt;
97 &lt;/head&gt;
98 &lt;body&gt;
99 &lt;button <strong>onclick="clickHandler(this)"</strong>&gt;
100 Click for awesomeness!
101 &lt;/button&gt;
102 &lt;/body&gt;
103 &lt;/html&gt;</pre>
104
105 <p>
106 Three things will need to change in order to make this work the way you expect
107 it to:
108 </p>
109
110 <ul>
111 <li>
112 The <code>clickHandler</code> definition needs to move into an external
113 JavaScript file (<code>popup.js</code> would be a good target).
114 </li>
115 <li>
116 The inline event handler definition must be rewritten in terms of
117 <code>addEventListener</code> and extracted into <code>popup.js</code>.
118 </li>
119 <li>
120 The <code>setTimeout</code> call will need to be rewritten to avoid
121 converting the string <code>"awesome(); totallyAwesome()"</code> into
122 JavaScript for execution.
123 </li>
124 </ul>
125
126 <p>
127 Those changes might look something like the following:
128 </p>
129
130 <pre>popup.js:
131 =========
132
133 function awesome() {
134 // Do something awesome!
135 }
136
137 function totallyAwesome() {
138 // do something TOTALLY awesome!
139 }
140
141 <strong>
142 function awesomeTask() {
143 awesome();
144 totallyAwesome();
145 }
146 </strong>
147
148 function clickHandler(e) {
149 setTimeout(<strong>awesomeTask</strong>, 1000);
150 }
151
152 // Add event listeners once the DOM has fully loaded by listening for the
153 // `DOMContentLoaded` event on the document, and adding your listeners to
154 // specific elements when it triggers.
155 document.addEventListener('DOMContentLoaded', function () {
156 document.querySelector('button').addEventListener('click', clickHandler);
157 });
158
159 popup.html:
160 ===========
161
162 &lt;!doctype html&gt;
163 &lt;html&gt;
164 &lt;head&gt;
165 &lt;title&gt;My Awesome Popup!&lt;/title&gt;
166 &lt;script <strong>src="popup.js"</strong>&gt;&lt;/script&gt;
167 &lt;/head&gt;
168 &lt;body&gt;
169 &lt;button&gt;Click for awesomeness!&lt;/button&gt;
170 &lt;/body&gt;
171 &lt;/html&gt;</pre>
172
173 <p>
174
175
176 <h3>Only local script and and object resources are loaded</h3>
177
178 <p>
179 Script and object resources can only be loaded from the extension's
180 package, not from the web at large. This ensures that your extension only
181 executes the code you've specifically approved, preventing an active network
182 attacker from maliciously redirecting your request for a resource.
183 </p>
184
185 <p>
186 Instead of writing code that depends on jQuery (or any other library) loading
187 from an external CDN, consider including the specific version of jQuery in
188 your extension package. That is, instead of:
189 </p>
190
191 <pre>&lt;!doctype html&gt;
192 &lt;html&gt;
193 &lt;head&gt;
194 &lt;title&gt;My Awesome Popup!&lt;/title&gt;
195 &lt;script src="<strong>http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jq uery.min.js</strong>"&gt;&lt;/script&gt;
196 &lt;/head&gt;
197 &lt;body&gt;
198 &lt;button&gt;Click for awesomeness!&lt;/button&gt;
199 &lt;/body&gt;
200 &lt;/html&gt;</pre>
201
202 <p>
203 Download the file, include it in your package, and write:
204 <p>
205
206 <pre>&lt;!doctype html&gt;
207 &lt;html&gt;
208 &lt;head&gt;
209 &lt;title&gt;My Awesome Popup!&lt;/title&gt;
210 &lt;script src="<strong>jquery.min.js</strong>"&gt;&lt;/script&gt;
211 &lt;/head&gt;
212 &lt;body&gt;
213 &lt;button&gt;Click for awesomeness!&lt;/button&gt;
214 &lt;/body&gt;
215 &lt;/html&gt;</pre>
216
217 <h2>Relaxing the default policy</h2>
218
219 <p>
220 There is no mechanism for relaxing the restriction against executing inline
221 JavaScript. In particular, setting a script policy that includes
222 <code>unsafe-inline</code> will have no effect. This is intentional.
223 </p>
224
225 <p>
226 If, on the other hand, you have a need for some external JavaScript or object
227 resources, you can relax the policy to a limited extent by whitelisting
228 secure origins from which scripts should be accepted. We want to ensure that
229 executable resources loaded with an extension's elevated permissions are
230 exactly the resources you expect, and haven't been replaced by an active
231 network attacker. As <a
232 href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack">man-in-the-middle
233 attacks</a> are both trivial and undetectable over HTTP, those origins will
234 not be accepted. Currently, we allow whitelisting origins with the following
235 schemes: <code>HTTPS</code>, <code>chrome-extension</code>, and
236 <code>chrome-extension-resource</code>.
237 </p>
238
239 <p>
240 A relaxed policy definition which allows script resources to be loaded from
241 <code>example.com</code> over HTTPS might look like:
242 </p>
243
244 <pre>{
245 ...,
246 "content_security_policy": "script-src 'self' https://example.com; object-src 'self'",
247 ...
248 }</pre>
249
250 <p class="note">
251 Note that both <code>script-src</code> and <code>object-src</code> are defined
252 by the policy. Chrome will not accept a policy that doesn't limit each of
253 these values to (at least) <code>'self'</code>.
254 </p>
255
256 <p>
257 Making use of Google Analytics is the canonical example for this sort of
258 policy definition. It's common enough that we've provided an Analytics
259 boilerplate of sorts in the <a href="samples.html#analytics">Event Tracking
260 with Google Analytics</a> sample extension, and a
261 <a href="tut_analytics.html">brief tutorial</a> that goes into more detail.
262 </p>
263
264 <h2>Tightening the default policy</h2>
265
266 <p>
267 You may, of course, tighten this policy to whatever extent your extension
268 allows in order to increase security at the expense of convenience. To specify
269 that your extension can only load resources of <em>any</em> type (images, etc)
270 from its own package, for example, a policy of <code>default-src 'self'</code>
271 would be appropriate. The <a href="samples.html#mappy">Mappy</a> sample
272 extension is a good example of an extension that's been locked down above and
273 beyond the defaults.
274 </p>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698