diff options
Diffstat (limited to 'chrome/common/extensions/docs')
-rw-r--r-- | chrome/common/extensions/docs/contentSecurityPolicy.html | 848 | ||||
-rw-r--r-- | chrome/common/extensions/docs/examples/tutorials/analytics.zip | bin | 14768 -> 14575 bytes | |||
-rw-r--r-- | chrome/common/extensions/docs/examples/tutorials/analytics/analytics.js | 32 | ||||
-rw-r--r-- | chrome/common/extensions/docs/examples/tutorials/analytics/manifest.json | 10 | ||||
-rw-r--r-- | chrome/common/extensions/docs/examples/tutorials/analytics/popup.html | 25 | ||||
-rw-r--r-- | chrome/common/extensions/docs/examples/tutorials/analytics/popup.js | 49 | ||||
-rw-r--r-- | chrome/common/extensions/docs/manifest.html | 45 | ||||
-rw-r--r-- | chrome/common/extensions/docs/samples.html | 9 | ||||
-rw-r--r-- | chrome/common/extensions/docs/samples.json | 9 | ||||
-rw-r--r-- | chrome/common/extensions/docs/static/contentSecurityPolicy.html | 272 | ||||
-rw-r--r-- | chrome/common/extensions/docs/static/manifest.html | 43 | ||||
-rw-r--r-- | chrome/common/extensions/docs/static/tut_analytics.html | 89 | ||||
-rw-r--r-- | chrome/common/extensions/docs/tut_analytics.html | 90 |
13 files changed, 1292 insertions, 229 deletions
diff --git a/chrome/common/extensions/docs/contentSecurityPolicy.html b/chrome/common/extensions/docs/contentSecurityPolicy.html new file mode 100644 index 0000000..4c4407f --- /dev/null +++ b/chrome/common/extensions/docs/contentSecurityPolicy.html @@ -0,0 +1,848 @@ +<!DOCTYPE html><!-- This page is a placeholder for generated extensions api doc. Note: + 1) The <head> information in this page is significant, should be uniform + across api docs and should be edited only with knowledge of the + templating mechanism. + 3) All <body>.innerHTML is genereated as an rendering step. If viewed in a + browser, it will be re-generated from the template, json schema and + authored overview content. + 4) The <body>.innerHTML is also generated by an offline step so that this + page may easily be indexed by search engines. +--><html xmlns="http://www.w3.org/1999/xhtml"><head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link href="css/ApiRefStyles.css" rel="stylesheet" type="text/css"> + <link href="css/print.css" rel="stylesheet" type="text/css" media="print"> + <script type="text/javascript" src="../../../third_party/jstemplate/jstemplate_compiled.js"> + </script> + <script type="text/javascript" src="js/api_page_generator.js"></script> + <script type="text/javascript" src="js/bootstrap.js"></script> + <script type="text/javascript" src="js/sidebar.js"></script> + <title>Content Security Policy (CSP) - Google Chrome Extensions - Google Code</title></head> + <body> <div id="devModeWarning" class="displayModeWarning"> + You are viewing extension docs in chrome via the 'file:' scheme: are you expecting to see local changes when you refresh? You'll need run chrome with --allow-file-access-from-files. + </div> + <div id="branchWarning" class="displayModeWarning"> + <span>WARNING: This is the <span id="branchName">BETA</span> documentation. + It may not work with the stable release of Chrome.</span> + <select id="branchChooser"> + <option>Choose a different version... + </option><option value="">Stable + </option><option value="beta">Beta + </option><option value="dev">Dev + </option><option value="trunk">Trunk + </option></select> + </div> + <div id="unofficialWarning" class="displayModeWarning"> + <span>WARNING: This is unofficial documentation. It may not work with the + current release of Chrome.</span> + <button id="goToOfficialDocs">Go to the official docs</button> + </div> + <div id="gc-container" class="labs"> + <!-- SUBTEMPLATES: DO NOT MOVE FROM THIS LOCATION --> + <!-- In particular, sub-templates that recurse, must be used by allowing + jstemplate to make a copy of the template in this section which + are not operated on by way of the jsskip="true" --> + <div style="display:none"> + + <!-- VALUE --> + <div id="valueTemplate"> + <dt> + <var>paramName</var> + <em> + + <!-- TYPE --> + <div style="display:inline"> + ( + <span class="optional">optional</span> + <span class="enum">enumerated</span> + <span id="typeTemplate"> + <span> + <a> Type</a> + </span> + <span> + <span> + array of <span><span></span></span> + </span> + <span>paramType</span> + <span></span> + </span> + </span> + ) + </div> + + </em> + </dt> + <dd class="todo"> + Undocumented. + </dd> + <dd> + Description of this parameter from the json schema. + </dd> + <dd> + This parameter was added in version + <b><span></span></b>. + You must omit this parameter in earlier versions, + and you may omit it in any version. If you require this + parameter, the manifest key + <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> + can ensure that your extension won't be run in an earlier browser version. + </dd> + + <!-- OBJECT PROPERTIES --> + <dd> + <dl> + <div> + <div> + </div> + </div> + </dl> + </dd> + + <!-- OBJECT METHODS --> + <dd> + <div></div> + </dd> + + <!-- OBJECT EVENT FIELDS --> + <dd> + <div></div> + </dd> + + <!-- FUNCTION PARAMETERS --> + <dd> + <div></div> + </dd> + + </div> <!-- /VALUE --> + + <div id="functionParametersTemplate"> + <h5>Parameters</h5> + <dl> + <div> + <div> + </div> + </div> + </dl> + </div> + + <!-- Individual subsections from the table of contents --> + <ol> + <li id="propertiesTocTemplate"> + <a href="#properties">Properties</a> + <ol> + <li> + <a href="#property-anchor">propertyName</a> + </li> + </ol> + </li> + <li id="methodsTocTemplate"> + <a>Methods</a> + <ol> + <li> + <a href="#method-anchor">methodName</a> + </li> + </ol> + </li> + <li id="eventsTocTemplate"> + <a>Events</a> + <ol> + <li> + <a href="#event-anchor">eventName</a> + </li> + </ol> + </li> + <li id="typesTocTemplate"> + <a href="#types">Types</a> + <ol> + <li> + <a href="#id-anchor">id</a> + <ol> + <div></div> + <div></div> + </ol> + </li> + </ol> + </li> + </ol> + </div> <!-- /SUBTEMPLATES --> + + <a id="top"></a> + <div id="skipto"> + <a href="#gc-pagecontent">Skip to page content</a> + <a href="#gc-toc">Skip to main navigation</a> + </div> + <!-- API HEADER --> + <table id="header" width="100%" cellspacing="0" border="0"> + <tbody><tr> + <td valign="middle"><a href="http://code.google.com/"><img src="images/code_labs_logo.gif" height="43" width="161" alt="Google Code Labs" style="border:0; margin:0;"></a></td> + <td valign="middle" width="100%" style="padding-left:0.6em;"> + <form action="http://www.google.com/cse" id="cse" style="margin-top:0.5em"> + <div id="gsc-search-box"> + <input type="hidden" name="cx" value="002967670403910741006:61_cvzfqtno"> + <input type="hidden" name="ie" value="UTF-8"> + <input type="text" name="q" value="" size="55"> + <input class="gsc-search-button" type="submit" name="sa" value="Search"> + <br> + <span class="greytext">e.g. "page action" or "tabs"</span> + </div> + </form> + + <script type="text/javascript" src="https://www.google.com/jsapi"></script> + <script type="text/javascript">google.load("elements", "1", {packages: "transliteration"});</script> + <script type="text/javascript" src="https://www.google.com/coop/cse/t13n?form=cse&t13n_langs=en"></script> + <script type="text/javascript" src="https://www.google.com/coop/cse/brand?form=cse&lang=en"></script> + </td> + </tr> + </tbody></table> + + <div id="codesiteContent" class=""> + + <a id="gc-topnav-anchor"></a> + <div id="gc-topnav"> + <h1>Google Chrome Extensions (<a href="http://code.google.com/labs/">Labs</a>)</h1> + <ul id="home" class="gc-topnav-tabs"> + <li id="home_link"> + <a href="index.html" title="Google Chrome Extensions home page">Home</a> + </li> + <li id="docs_link"> + <a href="docs.html" title="Official Google Chrome Extensions documentation">Docs</a> + </li> + <li id="faq_link"> + <a href="faq.html" title="Answers to frequently asked questions about Google Chrome Extensions">FAQ</a> + </li> + <li id="samples_link"> + <a href="samples.html" title="Sample extensions (with source code)">Samples</a> + </li> + <li id="group_link"> + <a href="http://groups.google.com/a/chromium.org/group/chromium-extensions" title="Google Chrome Extensions developer forum">Group</a> + </li> + <li id="so_link"> + <a href="http://stackoverflow.com/questions/tagged/google-chrome-extension" title="[google-chrome-extension] tag on Stack Overflow">Questions?</a> + </li> + </ul> + </div> <!-- end gc-topnav --> + + <div class="g-section g-tpl-170"> + <!-- SIDENAV --> + <div class="g-unit g-first" id="gc-toc"> + <ul> + <li><a href="getstarted.html">Getting Started</a></li> + <li><a href="overview.html">Overview</a></li> + <li><a href="whats_new.html">What's New?</a></li> + <li><h2><a href="devguide.html">Developer's Guide</a></h2> + <ul> + <li>Browser UI + <ul> + <li><a href="browserAction.html">Browser Actions</a></li> + <li><a href="contextMenus.html">Context Menus</a></li> + <li><a href="notifications.html">Desktop Notifications</a></li> + <li><a href="omnibox.html">Omnibox</a></li> + <li><a href="options.html">Options Pages</a></li> + <li><a href="override.html">Override Pages</a></li> + <li><a href="pageAction.html">Page Actions</a></li> + </ul> + </li> + <li>Browser Interaction + <ul> + <li><a href="bookmarks.html">Bookmarks</a></li> + <li><a href="cookies.html">Cookies</a></li> + <li><a href="devtools.html">Developer Tools</a></li> + <li><a href="events.html">Events</a></li> + <li><a href="history.html">History</a></li> + <li><a href="management.html">Management</a></li> + <li><a href="tabs.html">Tabs</a></li> + <li><a href="windows.html">Windows</a></li> + </ul> + </li> + <li>Implementation + <ul> + <li><a href="a11y.html">Accessibility</a></li> + <li><a href="background_pages.html">Background Pages</a></li> + <li><a href="content_scripts.html">Content Scripts</a></li> + <li><a href="xhr.html">Cross-Origin XHR</a></li> + <li><a href="i18n.html">Internationalization</a></li> + <li><a href="messaging.html">Message Passing</a></li> + <li><a href="permissions.html">Optional Permissions</a></li> + <li><a href="npapi.html">NPAPI Plugins</a></li> + </ul> + </li> + <li>Finishing + <ul> + <li><a href="hosting.html">Hosting</a></li> + <li><a href="external_extensions.html">Other Deployment Options</a></li> + </ul> + </li> + </ul> + </li> + <li><h2><a href="apps.html">Packaged Apps</a></h2></li> + <li><h2><a href="tutorials.html">Tutorials</a></h2> + <ul> + <li><a href="tut_debugging.html">Debugging</a></li> + <li><a href="tut_analytics.html">Google Analytics</a></li> + <li><a href="tut_oauth.html">OAuth</a></li> + </ul> + </li> + <li><h2>Reference</h2> + <ul> + <li>Formats + <ul> + <li><a href="manifest.html">Manifest Files</a></li> + <li><a href="match_patterns.html">Match Patterns</a></li> + </ul> + </li> + <li><a href="permission_warnings.html">Permission Warnings</a></li> + <li><a href="api_index.html">chrome.* APIs</a></li> + <li><a href="api_other.html">Other APIs</a></li> + </ul> + </li> + <li><h2><a href="samples.html">Samples</a></h2></li> + <div class="line"> </div> + <li><h2>More</h2> + <ul> + <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li> + <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Hosted Apps</a></li> + <li><a href="themes.html">Themes</a></li> + </ul> + </li> + </ul> + </div> + <script> + initToggles(); + </script> + + <div class="g-unit" id="gc-pagecontent"> + <div id="pageTitle"> + <h1 class="page_title">Content Security Policy (CSP)</h1> + </div> + <!-- TABLE OF CONTENTS --> + <div id="toc"> + <h2>Contents</h2> + <ol> + <li> + <a href="#H2-0">Default Policy Restrictions</a> + <ol> + <li> + <a href="#H3-1">Inline JavaScript will not be executed</a> + </li><li> + <a href="#H3-2">Only local script and and object resources are loaded</a> + </li> + </ol> + </li><li> + <a href="#H2-3">Relaxing the default policy</a> + <ol> + <li style="display: none; "> + <a>h3Name</a> + </li> + </ol> + </li><li> + <a href="#H2-4">Tightening the default policy</a> + <ol> + <li style="display: none; "> + <a>h3Name</a> + </li> + </ol> + </li> + <li style="display: none; "> + <a href="#apiReference">API reference</a> + <ol> + <div></div> + <div></div> + <div></div> + <div></div> + </ol> + </li> + </ol> + </div> + <!-- /TABLE OF CONTENTS --> + + <!-- Standard content lead-in for experimental API pages --> + <p id="classSummary" style="display: none; "> + For information on how to use experimental APIs, see the <a href="experimental.html">chrome.experimental.* APIs</a> page. + </p> + + <!-- STATIC CONTENT PLACEHOLDER --> + <div id="static"><div id="pageData-name" class="pageData">Content Security Policy (CSP)</div> +<div id="pageData-showTOC" class="pageData">true</div> + +<p> + In order to mitigate a large class of potental cross-site scripting issues, + Chrome's extension system has incorporated the general concept of + <a href="http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html"> + <strong>Content Security Policy (CSP)</strong> + </a>. This introduces some fairly strict policies that will make extensions + more secure by default, and provides you with the ability to create and + enforce rules governing the types of content that can be loaded and executed + by your extensions and applications. +</p> + +<p> + In general, CSP works as a black/whitelisting mechanism for resources loaded + or executed by your extensions. Defining a reasonable policy for your + extension enables you to carefully consider the resources that your extension + requires, and to ask the browser to ensure that those are the only resources + your extension has access to. These policies provide security over and above + the <a href="manifest.html#permissions">host permissions</a> your extension + requests; they're an additional layer of protection, not a replacement. +</p> + +<p> + On the web, such a policy is defined via an HTTP header or <code>meta</code> + element. Inside Chrome's extension system, neither is an appropriate + mechanism. Instead, an extension's policy is defined via the extension's + <a href="manifest.html"><code>manifest.json</code></a> file as follows: +</p> + +<pre>{ + ..., + "content_security_policy": "[POLICY STRING GOES HERE]" + ... +}</pre> + +<p class="note"> + For full details regarding CSP's syntax, please take a look at + <a href="http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#syntax"> + the Content Security Policy specification + </a>. +</p> + +<a name="H2-0"></a><h2>Default Policy Restrictions</h2> + +<p> + By default, Chrome defines a content security policy of: +</p> + +<pre>script-src 'self'; object-src 'self'</pre> + +<p> + This policy limits extensions in two ways: +</p> + +<a name="H3-1"></a><h3>Inline JavaScript will not be executed</h3> + +<p> + Inline JavaScript, as well as dangerous string-to-JavaScript methods like + <code>eval</code>, will not be executed. This restriction bans both inline + <code><script></code> blocks <strong>and</strong> inline event handlers + (e.g. <code><button onclick="..."></code>). +</p> + +<p> + The first restriction wipes out a huge class of cross-site scripting attacks + by making it impossible for you to accidentally execute script provided by a + malicious third-party. It does, however, require you to write your code with a + clean separation between content and behavior (which you should of course do + anyway, right?). An example might make this clearer. You might try to write a + <a href="browserAction.html#popups">Browser Action's popup</a> as a single + <code>popup.html</code> containing: +</p> + +<pre><!doctype html> +<html> + <head> + <title>My Awesome Popup!</title> + <script> + function awesome() { + // do something awesome! + } + + function totallyAwesome() { + // do something TOTALLY awesome! + } + + function clickHandler(element) { + setTimeout(<strong>"awesome(); totallyAwesome()"</strong>, 1000); + } + </script> + </head> + <body> + <button <strong>onclick="clickHandler(this)"</strong>> + Click for awesomeness! + </button> + </body> +</html></pre> + +<p> + Three things will need to change in order to make this work the way you expect + it to: +</p> + +<ul> + <li> + The <code>clickHandler</code> definition needs to move into an external + JavaScript file (<code>popup.js</code> would be a good target). + </li> + <li> + The inline event handler definition must be rewritten in terms of + <code>addEventListener</code> and extracted into <code>popup.js</code>. + </li> + <li> + The <code>setTimeout</code> call will need to be rewritten to avoid + converting the string <code>"awesome(); totallyAwesome()"</code> into + JavaScript for execution. + </li> +</ul> + +<p> + Those changes might look something like the following: +</p> + +<pre>popup.js: +========= + +function awesome() { + // Do something awesome! +} + +function totallyAwesome() { + // do something TOTALLY awesome! +} + +<strong> +function awesomeTask() { + awesome(); + totallyAwesome(); +} +</strong> + +function clickHandler(e) { + setTimeout(<strong>awesomeTask</strong>, 1000); +} + +// Add event listeners once the DOM has fully loaded by listening for the +// `DOMContentLoaded` event on the document, and adding your listeners to +// specific elements when it triggers. +document.addEventListener('DOMContentLoaded', function () { + document.querySelector('button').addEventListener('click', clickHandler); +}); + +popup.html: +=========== + +<!doctype html> +<html> + <head> + <title>My Awesome Popup!</title> + <script <strong>src="popup.js"</strong>></script> + </script> + </head> + <body> + <button>Click for awesomeness!</button> + </body> +</html></pre> + +<p> + + +</p><a name="H3-2"></a><h3>Only local script and and object resources are loaded</h3> + +<p> + Script and object resources can only be loaded from the extension's + package, not from the web at large. This ensures that your extension only + executes the code you've specifically approved, preventing an active network + attacker from maliciously redirecting your request for a resource. +</p> + +<p> + Instead of writing code that depends on jQuery (or any other library) loading + from an external CDN, consider including the specific version of jQuery in + your extension package. That is, instead of: +</p> + +<pre><!doctype html> +<html> + <head> + <title>My Awesome Popup!</title> + <script src="<strong>http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js</strong>"></script> + </script> + </head> + <body> + <button>Click for awesomeness!</button> + </body> +</html></pre> + +<p> + Download the file, include it in your package, and write: +</p><p> + +</p><pre><!doctype html> +<html> + <head> + <title>My Awesome Popup!</title> + <script src="<strong>jquery.min.js</strong>"></script> + </script> + </head> + <body> + <button>Click for awesomeness!</button> + </body> +</html></pre> + +<a name="H2-3"></a><h2>Relaxing the default policy</h2> + +<p> + There is no mechanism for relaxing the restriction against executing inline + JavaScript. In particular, setting a script policy that includes + <code>unsafe-inline</code> will have no effect. This is intentional. +</p> + +<p> + If, on the other hand, you have a need for some external JavaScript or object + resources, you can relax the policy to a limited extent by whitelisting + specific HTTPS origins from which scripts should be accepted. Whitelisting + insecure HTTP resources will have no effect. This is intentional, because + we want to ensure that executable resources loaded with an extension's + elevated permissions is exactly the resource you expect, and hasn't been + replaced by an active network attacker. As <a href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack">man-in-the-middle + attacks</a> are both trivial and undetectable over HTTP, only HTTPS origins + will be accepted. +</p> + +<p> + A relaxed policy definition which allows script resources to be loaded from + <code>example.com</code> over HTTPS might look like: +</p> + +<pre>{ + ..., + "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", + ... +}</pre> + +<p class="note"> + Note that both <code>script-src</code> and <code>object-src</code> are defined + by the policy. Chrome will not accept a policy that doesn't limit each of + these values to (at least) <code>'self'</code>. +</p> + +<p> + Making use of Google Analytics is the canonical example for this sort of + policy definition. It's common enough that we've provided an Analytics + boilerplate of sorts in the <a href="samples.html#analytics">Event Tracking + with Google Analytics</a> sample extension, and a +<a href="tut_analytics.html">brief tutorial</a> that goes into more detail. +</p> + +<a name="H2-4"></a><h2>Tightening the default policy</h2> + +<p> + You may, of course, tighten this policy to whatever extent your extension + allows in order to increase security at the expense of convenience. To specify + that your extension can only load resources of <em>any</em> type (images, etc) + from its own package, for example, a policy of <code>default-src 'self'</code> + would be appropriate. The <a href="samples.html#mappy">Mappy</a> sample + extension is a good example of an extension that's been locked down above and + beyond the defaults. +</p> +</div> + + <!-- API PAGE --> + <div class="apiPage" style="display: none; "> + <a name="apiReference"></a> + <h2>API reference: chrome.apiname </h2> + + <!-- PROPERTIES --> + <div class="apiGroup"> + <a name="properties"></a> + <h3 id="properties">Properties</h3> + + <div> + <a></a> + <h4>getLastError</h4> + <div class="summary"> + <!-- Note: intentionally longer 80 columns --> + <span>chrome.extension</span><span>lastError</span> + </div> + <div> + </div> + </div> + + </div> <!-- /apiGroup --> + + <!-- METHODS --> + <div id="methodsTemplate" class="apiGroup"> + <a></a> + <h3>Methods</h3> + + <!-- iterates over all functions --> + <div class="apiItem"> + <a></a> <!-- method-anchor --> + <h4>method name</h4> + + <div class="summary"><span>void</span> + <!-- Note: intentionally longer 80 columns --> + <span>chrome.module.methodName</span>(<span><span>, </span><span></span> + <var><span></span></var></span>)</div> + + <div class="description"> + <p class="todo">Undocumented.</p> + <p> + A description from the json schema def of the function goes here. + </p> + + <!-- PARAMETERS --> + <h4>Parameters</h4> + <dl> + <div> + <div> + </div> + </div> + </dl> + + <!-- RETURNS --> + <h4>Returns</h4> + <dl> + <div> + <div> + </div> + </div> + </dl> + + <!-- CALLBACK --> + <div> + <div> + <h4>Callback function</h4> + <p> + The callback <em>parameter</em> should specify a function + that looks like this: + </p> + <p> + If you specify the <em>callback</em> parameter, it should + specify a function that looks like this: + </p> + + <!-- Note: intentionally longer 80 columns --> + <pre>function(<span>Type param1, Type param2</span>) <span class="subdued">{...}</span>;</pre> + <dl> + <div> + <div> + </div> + </div> + </dl> + </div> + </div> + + <!-- MIN_VERSION --> + <p> + This function was added in version <b><span></span></b>. + If you require this function, the manifest key + <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> + can ensure that your extension won't be run in an earlier browser version. + </p> + </div> <!-- /description --> + + </div> <!-- /apiItem --> + + </div> <!-- /apiGroup --> + + <!-- EVENTS --> + <div id="eventsTemplate" class="apiGroup"> + <a></a> + <h3>Events</h3> + <!-- iterates over all events --> + <div class="apiItem"> + <a></a> + <h4>event name</h4> + + <div class="summary"> + <!-- Note: intentionally longer 80 columns --> + <span class="subdued">chrome.bookmarks</span><span>onEvent</span><span class="subdued">.addListener</span>(function(<span>Type param1, Type param2</span>) <span class="subdued">{...}</span><span>, Type opt_param1, Type opt_param2</span>); + </div> + + <div class="description"> + <p class="todo">Undocumented.</p> + <p> + A description from the json schema def of the event goes here. + </p> + + <!-- LISTENER PARAMETERS --> + <div> + <h4>Listener parameters</h4> + <dl> + <div> + <div> + </div> + </div> + </dl> + </div> + + <!-- EXTRA PARAMETERS --> + <div> + <h4>Extra parameters to addListener</h4> + <dl> + <div> + <div> + </div> + </div> + </dl> + </div> + + <!-- LISTENER RETURN VALUE --> + <h4>Listener returns</h4> + <dl> + <div> + <div> + </div> + </div> + </dl> + + </div> <!-- /description --> + </div> <!-- /apiItem --> + + </div> <!-- /apiGroup --> + + <!-- TYPES --> + <div class="apiGroup"> + <a name="types"></a> + <h3 id="types">Types</h3> + + <!-- iterates over all types --> + <div class="apiItem"> + <a></a> + <h4>type name</h4> + + <div> + </div> + + </div> <!-- /apiItem --> + + </div> <!-- /apiGroup --> + + </div> <!-- /apiPage --> + </div> <!-- /gc-pagecontent --> + </div> <!-- /g-section --> + </div> <!-- /codesiteContent --> + <div id="gc-footer" --=""> + <div class="text"> + <p> + Except as otherwise <a href="http://code.google.com/policies.html#restrictions">noted</a>, + the content of this page is licensed under the <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons + Attribution 3.0 License</a>, and code samples are licensed under the + <a rel="license" href="http://code.google.com/google_bsd_license.html">BSD License</a>. + </p> + <p> + ©2011 Google + </p> + +<!-- begin analytics --> +<script src="https://www.google-analytics.com/urchin.js" type="text/javascript"></script> +<script src="https://www.google-analytics.com/ga.js" type="text/javascript"></script> + +<script type="text/javascript"> + // chrome doc tracking + try { + var engdocs = _gat._getTracker("YT-10763712-2"); + engdocs._trackPageview(); + } catch(err) {} + + // code.google.com site-wide tracking + try { + _uacct="UA-18071-1"; + _uanchor=1; + _uff=0; + urchinTracker(); + } + catch(e) {/* urchinTracker not available. */} +</script> +<!-- end analytics --> + </div> + </div> <!-- /gc-footer --> + </div> <!-- /gc-container --> +</body></html> diff --git a/chrome/common/extensions/docs/examples/tutorials/analytics.zip b/chrome/common/extensions/docs/examples/tutorials/analytics.zip Binary files differindex 5ad25f9..5997e76 100644 --- a/chrome/common/extensions/docs/examples/tutorials/analytics.zip +++ b/chrome/common/extensions/docs/examples/tutorials/analytics.zip diff --git a/chrome/common/extensions/docs/examples/tutorials/analytics/analytics.js b/chrome/common/extensions/docs/examples/tutorials/analytics/analytics.js deleted file mode 100644 index 06945ce..0000000 --- a/chrome/common/extensions/docs/examples/tutorials/analytics/analytics.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this - * source code is governed by a BSD-style license that can be found in the - * LICENSE file. - * - * Below is a modified version of the Google Analytics asynchronous tracking - * code snippet. It has been modified to pull the HTTPS version of ga.js - * instead of the default HTTP version. It is recommended that you use this - * snippet instead of the standard tracking snippet provided when setting up - * a Google Analytics account. - * - * See http://code.google.com/apis/analytics/docs/tracking/asyncTracking.html - * for information on how to use the asynchronous tracking API. - * - * If you wish to use this file in your own extension, replace UA-12026369-1 - * with your own Google Analytics account number. Note that the default code - * will automatically track a page view for any page this file is included in. - * - * When including this file in your code, the best practice is to insert the - * <script src="analytics.js"></script> include at the top of the <body> - * section of your pages, after the opening <body> tag. - */ - -var _gaq = _gaq || []; -_gaq.push(['_setAccount', 'UA-12026369-1']); -_gaq.push(['_trackPageview']); - -(function() { - var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; - ga.src = 'https://ssl.google-analytics.com/ga.js'; - var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); -})();
\ No newline at end of file diff --git a/chrome/common/extensions/docs/examples/tutorials/analytics/manifest.json b/chrome/common/extensions/docs/examples/tutorials/analytics/manifest.json index 55e3f7b..11f90a0 100644 --- a/chrome/common/extensions/docs/examples/tutorials/analytics/manifest.json +++ b/chrome/common/extensions/docs/examples/tutorials/analytics/manifest.json @@ -1,10 +1,7 @@ { "name": "Event Tracking with Google Analytics", - "version": "1.0.0", + "version": "2.0.0", "description": "A sample extension which uses Google Analytics to track usage.", - "background": { - "scripts": ["analytics.js"] - }, "browser_action": { "default_title": "Open the popup", "default_icon": "analytics-extension-icon-19.png", @@ -13,5 +10,8 @@ "icons": { "48": "analytics-extension-icon-48.png", "128": "analytics-extension-icon-128.png" - } + }, + + "manifest_version": 2, + "content_security_policy": "script-src 'self' https://ssl.google-analytics.com; object-src 'self'" } diff --git a/chrome/common/extensions/docs/examples/tutorials/analytics/popup.html b/chrome/common/extensions/docs/examples/tutorials/analytics/popup.html index 19284a8..9a76c26 100644 --- a/chrome/common/extensions/docs/examples/tutorials/analytics/popup.html +++ b/chrome/common/extensions/docs/examples/tutorials/analytics/popup.html @@ -1,6 +1,6 @@ <!DOCTYPE html> <!-- - * Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this + * Copyright (c) 2012 The Chromium Authors. All rights reserved. Use of this * source code is governed by a BSD-style license that can be found in the * LICENSE file. --> @@ -17,25 +17,16 @@ text-align: center; } </style> + <script src="popup.js"></script> </head> <body> - <script src="analytics.js"></script> - <script> - /** - * Tracks a single button click. You can use the _trackEvent command - * to track user interactions with different parts of your extension. - */ - function trackButton(button_id) { - _gaq.push(['_trackEvent', 'button' + button_id, 'clicked']); - } - </script> <h1>Popup</h1> <p>Track the following actions:</p> - <button onclick="trackButton(1);">Button 1</button> - <button onclick="trackButton(2);">Button 2</button> - <button onclick="trackButton(3);">Button 3</button> - <button onclick="trackButton(4);">Button 4</button> - <button onclick="trackButton(5);">Button 5</button> - <button onclick="trackButton(6);">Button 6</button> + <button id='button1'>Button 1</button> + <button id='button2'>Button 2</button> + <button id='button3'>Button 3</button> + <button id='button4'>Button 4</button> + <button id='button5'>Button 5</button> + <button id='button6'>Button 6</button> </body> </html> diff --git a/chrome/common/extensions/docs/examples/tutorials/analytics/popup.js b/chrome/common/extensions/docs/examples/tutorials/analytics/popup.js new file mode 100644 index 0000000..160fe15 --- /dev/null +++ b/chrome/common/extensions/docs/examples/tutorials/analytics/popup.js @@ -0,0 +1,49 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * Add your Analytics tracking ID here. + */ +var _AnalyticsCode = 'UA-XXXXXX-X'; + +/** + * Below is a modified version of the Google Analytics asynchronous tracking + * code snippet. It has been modified to pull the HTTPS version of ga.js + * instead of the default HTTP version. It is recommended that you use this + * snippet instead of the standard tracking snippet provided when setting up + * a Google Analytics account. + */ +var _gaq = _gaq || []; +_gaq.push(['_setAccount', _AnalyticsCode]); +_gaq.push(['_trackPageview']); + +(function() { + var ga = document.createElement('script'); + ga.type = 'text/javascript'; + ga.async = true; + ga.src = 'https://ssl.google-analytics.com/ga.js'; + var s = document.getElementsByTagName('script')[0]; + s.parentNode.insertBefore(ga, s); +})(); + +/** + * Track a click on a button using the asynchronous tracking API. + * + * See http://code.google.com/apis/analytics/docs/tracking/asyncTracking.html + * for information on how to use the asynchronous tracking API. + */ +function trackButtonClick(e) { + _gaq.push(['_trackEvent', e.target.id, 'clicked']); +} + +/** + * Now set up your event handlers for the popup's `button` elements once the + * popup's DOM has loaded. + */ +document.addEventListener('DOMContentLoaded', function () { + var buttons = document.querySelectorAll('button'); + for (var i = 0; i < buttons.length; i++) { + buttons[i].addEventListener('click', trackButtonClick); + } +}); diff --git a/chrome/common/extensions/docs/manifest.html b/chrome/common/extensions/docs/manifest.html index e1f4746..9fcf0be 100644 --- a/chrome/common/extensions/docs/manifest.html +++ b/chrome/common/extensions/docs/manifest.html @@ -334,8 +334,6 @@ </li><li> <a href="#description">description</a> </li><li> - <a href="#content_security_policy">content_security_policy</a> - </li><li> <a href="#homepage_url">homepage_url</a> </li><li> <a href="#icons">icons</a> @@ -421,7 +419,7 @@ are <b>name</b> and <b>version</b>. "<a href="background_pages.html">background</a>": {...}, "<a href="override.html">chrome_url_overrides</a>": {...}, "<a href="content_scripts.html">content_scripts</a>": [...], - "<a href="#content_security_policy">content_security_policy</a>": "<em>policyString</em>", + "<a href="contentSecurityPolicy.html">content_security_policy</a>": "<em>policyString</em>", "<a href="fileBrowserHandler.html">file_browser_handlers</a>": [...], "<a href="#homepage_url">homepage_url</a>": "http://<em>path/to/homepage</em>", "<a href="#incognito">incognito</a>": "spanning" <em>or</em> "split", @@ -493,47 +491,6 @@ You can specify locale-specific strings for this field; see <a href="i18n.html">Internationalization</a> for details. </p> -<h3 id="content_security_policy">content_security_policy</h3> - -<p> -A security policy to apply to resources in your extension. You can use this -policy to help prevent cross-site scripting vulnerabilities in your extension. -By default, the extension system enforces the following policy: -</p> - -<pre>script-src 'self'; object-src 'self'</pre> - -<p> -Extensions can tighten their policy using the -<code>content_security_policy</code> manifest attribute. For example, to -specify that your extension loads resources only from its own package, use the -following policy: -</p> - -<pre>"content_security_policy": "default-src 'self' " </pre> - -<p> -If you need to load resources from websites, -you can add them to the whitelist. -For example, if your extension uses Google Analytics, -you might use the following policy: -</p> - -<pre>"content_security_policy": "default-src 'self' https://ssl.google-analytics.com"</pre> - -<p> -The extension system will prevent you including insecure resources -for <code>script-src</code> or <code>object-src</code>. If you are using -<code>eval</code> to parse JSON, please consider using <code>JSON.parse</code> -instead. -</p> - -<p> -For details, see the -<a href="http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html">Content Security Policy specification</a>. -</p> - - <h3 id="homepage_url">homepage_url</h3> <p> diff --git a/chrome/common/extensions/docs/samples.html b/chrome/common/extensions/docs/samples.html index 4db49c0..2677e5b 100644 --- a/chrome/common/extensions/docs/samples.html +++ b/chrome/common/extensions/docs/samples.html @@ -368,7 +368,7 @@ "5d81304a17cf7ac2887484f730fbd2b01e51e166": "CONTEXT MENUS SAMPLE SHOWS SOME OF THE FEATURES OF THE CONTEXT MENUS API BACKGROUND_PAGE CONTEXTMENUS CHROME.CONTEXTMENUS.CREATE", "4daa6becd0899a54776d9cf7f09613ed1a9f4d77": "COOKIE API TEST EXTENSION TESTING COOKIE API BACKGROUND_PAGE BROWSER_ACTION COOKIES TABS CHROME.BROWSERACTION.ONCLICKED CHROME.COOKIES.GET CHROME.COOKIES.GETALL CHROME.COOKIES.ONCHANGED CHROME.COOKIES.REMOVE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL", "028eb5364924344029bcbe1d527f132fc72b34e5": "EMAIL THIS PAGE (BY GOOGLE) THIS EXTENSION ADDS AN EMAIL BUTTON TO THE TOOLBAR WHICH ALLOWS YOU TO EMAIL THE PAGE LINK USING YOUR DEFAULT MAIL CLIENT OR GMAIL. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.CONNECT CHROME.EXTENSION.ONCONNECT CHROME.TABS.CREATE CHROME.TABS.EXECUTESCRIPT CHROME.TABS.UPDATE", - "763a08e9b06595d785568a8d392b95a2f3700258": "EVENT TRACKING WITH GOOGLE ANALYTICS A SAMPLE EXTENSION WHICH USES GOOGLE ANALYTICS TO TRACK USAGE. BACKGROUND_PAGE BROWSER_ACTION", + "763a08e9b06595d785568a8d392b95a2f3700258": "EVENT TRACKING WITH GOOGLE ANALYTICS A SAMPLE EXTENSION WHICH USES GOOGLE ANALYTICS TO TRACK USAGE. BROWSER_ACTION", "4efa12eaaa442b6b7c880e7a38ceeb0cff7e8b77": "FIREPHP FOR CHROME EXTENDS THE DEVELOPER TOOLS, ADDING SUPPORT FOR PARSING FIREPHP MESSAGES FROM SERVER BACKGROUND_PAGE DEVTOOLS_PAGE TABS CHROME.DEVTOOLS.NETWORK.GETHAR CHROME.DEVTOOLS.NETWORK.ONREQUESTFINISHED CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST CHROME.TABS.EXECUTESCRIPT", "8b0dd31216235941bdd8eb33fda915ef5cf79a82": "GOOGLE CALENDAR CHECKER (BY GOOGLE) QUICKLY SEE THE TIME UNTIL YOUR NEXT MEETING FROM ANY OF YOUR CALENDARS. CLICK ON THE BUTTON TO BE TAKEN TO YOUR CALENDAR. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETICON CHROME.BROWSERACTION.SETTITLE CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST CHROME.I18N.GETMESSAGE CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.ONUPDATED CHROME.TABS.UPDATE", "4e35caa9742fb82dbd628892d23a781614f6eff6": "GOOGLE DOCUMENT LIST VIEWER DEMONSTRATES HOW TO USE OAUTH TO CONNECT THE GOOGLE DOCUMENTS LIST DATA API. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.SETBADGETEXT CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE", @@ -1605,9 +1605,6 @@ </h2> <p class="metadata features">Uses <span> - <strong>background_page</strong><span style="display: none; ">, </span> - <span> and</span> - </span><span> <strong>browser_action</strong><span style="display: none; ">, </span> <span style="display: none; "> and</span> </span> @@ -1623,11 +1620,11 @@ <div class="sourcefiles"><strong>Source files:</strong> <ul> <li> - <code><a target="_blank" href="examples/tutorials/analytics/analytics.js">analytics.js</a></code> - </li><li> <code><a target="_blank" href="examples/tutorials/analytics/manifest.json">manifest.json</a></code> </li><li> <code><a target="_blank" href="examples/tutorials/analytics/popup.html">popup.html</a></code> + </li><li> + <code><a target="_blank" href="examples/tutorials/analytics/popup.js">popup.js</a></code> </li> </ul> </div> diff --git a/chrome/common/extensions/docs/samples.json b/chrome/common/extensions/docs/samples.json index e0ad414..3ba3573 100644 --- a/chrome/common/extensions/docs/samples.json +++ b/chrome/common/extensions/docs/samples.json @@ -868,7 +868,6 @@ "crx_path": null, "description": "A sample extension which uses Google Analytics to track usage.", "features": [ - "background_page", "browser_action" ], "icon": "analytics-extension-icon-128.png", @@ -877,13 +876,13 @@ "packaged_app": false, "path": "examples\/tutorials\/analytics\/", "protocols": [], - "search_string": "EVENT TRACKING WITH GOOGLE ANALYTICS A SAMPLE EXTENSION WHICH USES GOOGLE ANALYTICS TO TRACK USAGE. BACKGROUND_PAGE BROWSER_ACTION", + "search_string": "EVENT TRACKING WITH GOOGLE ANALYTICS A SAMPLE EXTENSION WHICH USES GOOGLE ANALYTICS TO TRACK USAGE. BROWSER_ACTION", "source_files": [ - "analytics.js", "manifest.json", - "popup.html" + "popup.html", + "popup.js" ], - "source_hash": "48c84c58d7b3673be329cedb1b1351a6a23958ff", + "source_hash": "7465c76ddd9945e077724c3d5649d12c8fde8e8c", "zip_path": "examples\/tutorials\/analytics.zip" }, { diff --git a/chrome/common/extensions/docs/static/contentSecurityPolicy.html b/chrome/common/extensions/docs/static/contentSecurityPolicy.html new file mode 100644 index 0000000..494387e --- /dev/null +++ b/chrome/common/extensions/docs/static/contentSecurityPolicy.html @@ -0,0 +1,272 @@ +<div id="pageData-name" class="pageData">Content Security Policy (CSP)</div> +<div id="pageData-showTOC" class="pageData">true</div> + +<p> + In order to mitigate a large class of potental cross-site scripting issues, + Chrome's extension system has incorporated the general concept of + <a href="http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html"> + <strong>Content Security Policy (CSP)</strong> + </a>. This introduces some fairly strict policies that will make extensions + more secure by default, and provides you with the ability to create and + enforce rules governing the types of content that can be loaded and executed + by your extensions and applications. +</p> + +<p> + In general, CSP works as a black/whitelisting mechanism for resources loaded + or executed by your extensions. Defining a reasonable policy for your + extension enables you to carefully consider the resources that your extension + requires, and to ask the browser to ensure that those are the only resources + your extension has access to. These policies provide security over and above + the <a href="manifest.html#permissions">host permissions</a> your extension + requests; they're an additional layer of protection, not a replacement. +</p> + +<p> + On the web, such a policy is defined via an HTTP header or <code>meta</code> + element. Inside Chrome's extension system, neither is an appropriate + mechanism. Instead, an extension's policy is defined via the extension's + <a href="manifest.html"><code>manifest.json</code></a> file as follows: +</p> + +<pre>{ + ..., + "content_security_policy": "[POLICY STRING GOES HERE]" + ... +}</pre> + +<p class="note"> + For full details regarding CSP's syntax, please take a look at + <a href="http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#syntax"> + the Content Security Policy specification + </a>. +</p> + +<h2>Default Policy Restrictions</h2> + +<p> + By default, Chrome defines a content security policy of: +</p> + +<pre>script-src 'self'; object-src 'self'</pre> + +<p> + This policy limits extensions in two ways: +</p> + +<h3>Inline JavaScript will not be executed</h3> + +<p> + Inline JavaScript, as well as dangerous string-to-JavaScript methods like + <code>eval</code>, will not be executed. This restriction bans both inline + <code><script></code> blocks <strong>and</strong> inline event handlers + (e.g. <code><button onclick="..."></code>). +</p> + +<p> + The first restriction wipes out a huge class of cross-site scripting attacks + by making it impossible for you to accidentally execute script provided by a + malicious third-party. It does, however, require you to write your code with a + clean separation between content and behavior (which you should of course do + anyway, right?). An example might make this clearer. You might try to write a + <a href="browserAction.html#popups">Browser Action's popup</a> as a single + <code>popup.html</code> containing: +</p> + +<pre><!doctype html> +<html> + <head> + <title>My Awesome Popup!</title> + <script> + function awesome() { + // do something awesome! + } + + function totallyAwesome() { + // do something TOTALLY awesome! + } + + function clickHandler(element) { + setTimeout(<strong>"awesome(); totallyAwesome()"</strong>, 1000); + } + </script> + </head> + <body> + <button <strong>onclick="clickHandler(this)"</strong>> + Click for awesomeness! + </button> + </body> +</html></pre> + +<p> + Three things will need to change in order to make this work the way you expect + it to: +</p> + +<ul> + <li> + The <code>clickHandler</code> definition needs to move into an external + JavaScript file (<code>popup.js</code> would be a good target). + </li> + <li> + The inline event handler definition must be rewritten in terms of + <code>addEventListener</code> and extracted into <code>popup.js</code>. + </li> + <li> + The <code>setTimeout</code> call will need to be rewritten to avoid + converting the string <code>"awesome(); totallyAwesome()"</code> into + JavaScript for execution. + </li> +</ul> + +<p> + Those changes might look something like the following: +</p> + +<pre>popup.js: +========= + +function awesome() { + // Do something awesome! +} + +function totallyAwesome() { + // do something TOTALLY awesome! +} + +<strong> +function awesomeTask() { + awesome(); + totallyAwesome(); +} +</strong> + +function clickHandler(e) { + setTimeout(<strong>awesomeTask</strong>, 1000); +} + +// Add event listeners once the DOM has fully loaded by listening for the +// `DOMContentLoaded` event on the document, and adding your listeners to +// specific elements when it triggers. +document.addEventListener('DOMContentLoaded', function () { + document.querySelector('button').addEventListener('click', clickHandler); +}); + +popup.html: +=========== + +<!doctype html> +<html> + <head> + <title>My Awesome Popup!</title> + <script <strong>src="popup.js"</strong>></script> + </script> + </head> + <body> + <button>Click for awesomeness!</button> + </body> +</html></pre> + +<p> + + +<h3>Only local script and and object resources are loaded</h3> + +<p> + Script and object resources can only be loaded from the extension's + package, not from the web at large. This ensures that your extension only + executes the code you've specifically approved, preventing an active network + attacker from maliciously redirecting your request for a resource. +</p> + +<p> + Instead of writing code that depends on jQuery (or any other library) loading + from an external CDN, consider including the specific version of jQuery in + your extension package. That is, instead of: +</p> + +<pre><!doctype html> +<html> + <head> + <title>My Awesome Popup!</title> + <script src="<strong>http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js</strong>"></script> + </script> + </head> + <body> + <button>Click for awesomeness!</button> + </body> +</html></pre> + +<p> + Download the file, include it in your package, and write: +<p> + +<pre><!doctype html> +<html> + <head> + <title>My Awesome Popup!</title> + <script src="<strong>jquery.min.js</strong>"></script> + </script> + </head> + <body> + <button>Click for awesomeness!</button> + </body> +</html></pre> + +<h2>Relaxing the default policy</h2> + +<p> + There is no mechanism for relaxing the restriction against executing inline + JavaScript. In particular, setting a script policy that includes + <code>unsafe-inline</code> will have no effect. This is intentional. +</p> + +<p> + If, on the other hand, you have a need for some external JavaScript or object + resources, you can relax the policy to a limited extent by whitelisting + specific HTTPS origins from which scripts should be accepted. Whitelisting + insecure HTTP resources will have no effect. This is intentional, because + we want to ensure that executable resources loaded with an extension's + elevated permissions is exactly the resource you expect, and hasn't been + replaced by an active network attacker. As <a + href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack">man-in-the-middle + attacks</a> are both trivial and undetectable over HTTP, only HTTPS origins + will be accepted. +</p> + +<p> + A relaxed policy definition which allows script resources to be loaded from + <code>example.com</code> over HTTPS might look like: +</p> + +<pre>{ + ..., + "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", + ... +}</pre> + +<p class="note"> + Note that both <code>script-src</code> and <code>object-src</code> are defined + by the policy. Chrome will not accept a policy that doesn't limit each of + these values to (at least) <code>'self'</code>. +</p> + +<p> + Making use of Google Analytics is the canonical example for this sort of + policy definition. It's common enough that we've provided an Analytics + boilerplate of sorts in the <a href="samples.html#analytics">Event Tracking + with Google Analytics</a> sample extension, and a +<a href="tut_analytics.html">brief tutorial</a> that goes into more detail. +</p> + +<h2>Tightening the default policy</h2> + +<p> + You may, of course, tighten this policy to whatever extent your extension + allows in order to increase security at the expense of convenience. To specify + that your extension can only load resources of <em>any</em> type (images, etc) + from its own package, for example, a policy of <code>default-src 'self'</code> + would be appropriate. The <a href="samples.html#mappy">Mappy</a> sample + extension is a good example of an extension that's been locked down above and + beyond the defaults. +</p> diff --git a/chrome/common/extensions/docs/static/manifest.html b/chrome/common/extensions/docs/static/manifest.html index d05cdaa..2e58812 100644 --- a/chrome/common/extensions/docs/static/manifest.html +++ b/chrome/common/extensions/docs/static/manifest.html @@ -39,7 +39,7 @@ are <b>name</b> and <b>version</b>. "<a href="background_pages.html">background</a>": {...}, "<a href="override.html">chrome_url_overrides</a>": {...}, "<a href="content_scripts.html">content_scripts</a>": [...], - "<a href="#content_security_policy">content_security_policy</a>": "<em>policyString</em>", + "<a href="contentSecurityPolicy.html">content_security_policy</a>": "<em>policyString</em>", "<a href="fileBrowserHandler.html">file_browser_handlers</a>": [...], "<a href="#homepage_url">homepage_url</a>": "http://<em>path/to/homepage</em>", "<a href="#incognito">incognito</a>": "spanning" <em>or</em> "split", @@ -111,47 +111,6 @@ You can specify locale-specific strings for this field; see <a href="i18n.html">Internationalization</a> for details. </p> -<h3 id="content_security_policy">content_security_policy</h3> - -<p> -A security policy to apply to resources in your extension. You can use this -policy to help prevent cross-site scripting vulnerabilities in your extension. -By default, the extension system enforces the following policy: -</p> - -<pre>script-src 'self'; object-src 'self'</pre> - -<p> -Extensions can tighten their policy using the -<code>content_security_policy</code> manifest attribute. For example, to -specify that your extension loads resources only from its own package, use the -following policy: -</p> - -<pre>"content_security_policy": "default-src 'self' " </pre> - -<p> -If you need to load resources from websites, -you can add them to the whitelist. -For example, if your extension uses Google Analytics, -you might use the following policy: -</p> - -<pre>"content_security_policy": "default-src 'self' https://ssl.google-analytics.com"</pre> - -<p> -The extension system will prevent you including insecure resources -for <code>script-src</code> or <code>object-src</code>. If you are using -<code>eval</code> to parse JSON, please consider using <code>JSON.parse</code> -instead. -</p> - -<p> -For details, see the -<a href="http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html">Content Security Policy specification</a>. -</p> - - <h3 id="homepage_url">homepage_url</h3> <p> diff --git a/chrome/common/extensions/docs/static/tut_analytics.html b/chrome/common/extensions/docs/static/tut_analytics.html index f1a8bc1..88c3f95 100644 --- a/chrome/common/extensions/docs/static/tut_analytics.html +++ b/chrome/common/extensions/docs/static/tut_analytics.html @@ -13,7 +13,7 @@ extension.</p> <p> You will also need a <a href="http://www.google.com/analytics">Google - Analytics account</a> set up to track your extension. Note that when setting + Analytics account</a> set up to track your extension. Note that when setting up the account, you can use any value in the Website's URL field, as your extension will not have an URL of its own. </p> @@ -24,26 +24,20 @@ extension.</p> alt="The analytics setup with info for a chrome extension filled out." /> </p> -<p> - Also note that Google Analytics requires version <strong>4.0.302.2</strong> - of Google Chrome to work correctly. Users with an earlier version of Google - Chrome will not show up on your Google Analytics reports. View - <a href="faq.html#faq-dev-14">this FAQ entry</a> to learn how to check which - version of Google Chrome is deployed to which platform. -</p> - <h2 id="toc-installing">Installing the tracking code</h2> <p> The standard Google Analytics tracking code snippet fetches a file named <code>ga.js</code> from an SSL protected URL if the current page - was loaded using the <code>https://</code> protocol. <strong>It is strongly - advised to use the SSL protected ga.js in an extension</strong>, - but Google Chrome extension - pages are hosted under <code>chrome-extension://</code> URLs, so the tracking - snippet must be modified slightly to pull <code>ga.js</code> directly from - <code>https://ssl.google-analytics.com/ga.js</code> instead of the default - location. + was loaded using the <code>https://</code> protocol. <strong>Chrome + extensions and applications may <em>only</em> use the SSL-protected version of + <code>ga.js</code></strong>. Loading <code>ga.js</code> over insecure HTTP is + disallowed by Chrome's default <a href="contentSecurityPolicy.html">Content + Security Policy</a>. This, plus the fact that Chrome extensions are hosted + under the <code>chrome-extension://</code> schema, requires a slight + modification to the usual tracking snippet to pull <code>ga.js</code> directly + from <code>https://ssl.google-analytics.com/ga.js</code> instead of the + default location. </p> <p> @@ -61,29 +55,45 @@ extension.</p> </pre> <p> - Here is a background page which loads the asynchronous tracking code and + You'll also need to ensure that your extension has access to load the resource + by relaxing the default content security policy. The policy definition in your + <a href="manifest.html"><code>manifest.json</code></a> might look like: +</p> + +<pre>{ + ..., + "content_security_policy": "script-src 'self' https://ssl.google-analytics.com; object-src 'self'", + ... +}</pre> + +<p> + Here is a popup page (<code>popup.html</code>) which loads the asynchronous + tracking code via an external JavaScript file (<code>popup.js</code>) and tracks a single page view: </p> -<pre> +<pre>popup.js: +========= + +var _gaq = _gaq || []; +_gaq.push(['_setAccount', 'UA-XXXXXXXX-X']); +_gaq.push(['_trackPageview']); + +(function() { + var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; + ga.src = 'https://ssl.google-analytics.com/ga.js'; + var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); +})(); + +popup.html: +=========== <!DOCTYPE html> <html> <head> ... + <script src="popup.js"></script> </head> <body> - <script> - var _gaq = _gaq || []; - _gaq.push(['_setAccount', 'UA-XXXXXXXX-X']); - _gaq.push(['_trackPageview']); - - (function() { - var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; - ga.src = 'https://ssl.google-analytics.com/ga.js'; - var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); - })(); - </script> - ... </body> </html> @@ -142,9 +152,9 @@ extension.</p> </p> <pre> - <button>Button 1</button> - <button>Button 2</button> - <button>Button 3</button> + <button id='button1'>Button 1</button> + <button id='button2'>Button 2</button> + <button id='button3'>Button 3</button> </pre> <p> @@ -152,19 +162,20 @@ extension.</p> </p> <pre> - function trackButton(button_id) { - _gaq.push(['_trackEvent', 'button' + button_id, 'clicked']); + function trackButton(e) { + _gaq.push(['_trackEvent', e.target.id, 'clicked']); }; </pre> <p> - And call it when each button is pressed: + And use it as an event handler for each button's click: </p> <pre> - <button onclick="trackButton(1);">Button 1</button> - <button onclick="trackButton(2);">Button 2</button> - <button onclick="trackButton(3);">Button 3</button> + var buttons = document.querySelectorAll('button'); + for (var i = 0; i < buttons.length; i++) { + buttons[i].addEventListener('click', trackButtonClick); + } </pre> <p> diff --git a/chrome/common/extensions/docs/tut_analytics.html b/chrome/common/extensions/docs/tut_analytics.html index 180cf1e..74bca00 100644 --- a/chrome/common/extensions/docs/tut_analytics.html +++ b/chrome/common/extensions/docs/tut_analytics.html @@ -394,7 +394,7 @@ extension.</p> <p> You will also need a <a href="http://www.google.com/analytics">Google - Analytics account</a> set up to track your extension. Note that when setting + Analytics account</a> set up to track your extension. Note that when setting up the account, you can use any value in the Website's URL field, as your extension will not have an URL of its own. </p> @@ -403,26 +403,20 @@ extension.</p> <img src="images/tut_analytics/screenshot01.png" style="width:400px;height:82px;" alt="The analytics setup with info for a chrome extension filled out."> </p> -<p> - Also note that Google Analytics requires version <strong>4.0.302.2</strong> - of Google Chrome to work correctly. Users with an earlier version of Google - Chrome will not show up on your Google Analytics reports. View - <a href="faq.html#faq-dev-14">this FAQ entry</a> to learn how to check which - version of Google Chrome is deployed to which platform. -</p> - <h2 id="toc-installing">Installing the tracking code</h2> <p> The standard Google Analytics tracking code snippet fetches a file named <code>ga.js</code> from an SSL protected URL if the current page - was loaded using the <code>https://</code> protocol. <strong>It is strongly - advised to use the SSL protected ga.js in an extension</strong>, - but Google Chrome extension - pages are hosted under <code>chrome-extension://</code> URLs, so the tracking - snippet must be modified slightly to pull <code>ga.js</code> directly from - <code>https://ssl.google-analytics.com/ga.js</code> instead of the default - location. + was loaded using the <code>https://</code> protocol. <strong>Chrome + extensions and applications may <em>only</em> use the SSL-protected version of + <code>ga.js</code></strong>. Loading <code>ga.js</code> over insecure HTTP is + disallowed by Chrome's default <a href="contentSecurityPolicy.html">Content + Security Policy</a>. This, plus the fact that Chrome extensions are hosted + under the <code>chrome-extension://</code> schema, requires a slight + modification to the usual tracking snippet to pull <code>ga.js</code> directly + from <code>https://ssl.google-analytics.com/ga.js</code> instead of the + default location. </p> <p> @@ -439,28 +433,45 @@ extension.</p> </pre> <p> - Here is a background page which loads the asynchronous tracking code and + You'll also need to ensure that your extension has access to load the resource + by relaxing the default content security policy. The policy definition in your + <a href="manifest.html"><code>manifest.json</code></a> might look like: +</p> + +<pre>{ + ..., + "content_security_policy": "script-src 'self' https://ssl.google-analytics.com; object-src 'self'", + ... +}</pre> + +<p> + Here is a popup page (<code>popup.html</code>) which loads the asynchronous + tracking code via an external JavaScript file (<code>popup.js</code>) and tracks a single page view: </p> -<pre><!DOCTYPE html> +<pre>popup.js: +========= + +var _gaq = _gaq || []; +_gaq.push(['_setAccount', 'UA-XXXXXXXX-X']); +_gaq.push(['_trackPageview']); + +(function() { + var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; + ga.src = 'https://ssl.google-analytics.com/ga.js'; + var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); +})(); + +popup.html: +=========== +<!DOCTYPE html> <html> <head> ... + <script src="popup.js"></script> </head> <body> - <script> - var _gaq = _gaq || []; - _gaq.push(['_setAccount', 'UA-XXXXXXXX-X']); - _gaq.push(['_trackPageview']); - - (function() { - var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; - ga.src = 'https://ssl.google-analytics.com/ga.js'; - var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); - })(); - </script> - ... </body> </html> @@ -514,27 +525,28 @@ extension.</p> three buttons users may click: </p> -<pre> <button>Button 1</button> - <button>Button 2</button> - <button>Button 3</button> +<pre> <button id='button1'>Button 1</button> + <button id='button2'>Button 2</button> + <button id='button3'>Button 3</button> </pre> <p> Write a function that sends click events to Google Analytics: </p> -<pre> function trackButton(button_id) { - _gaq.push(['_trackEvent', 'button' + button_id, 'clicked']); +<pre> function trackButton(e) { + _gaq.push(['_trackEvent', e.target.id, 'clicked']); }; </pre> <p> - And call it when each button is pressed: + And use it as an event handler for each button's click: </p> -<pre> <button onclick="trackButton(1);">Button 1</button> - <button onclick="trackButton(2);">Button 2</button> - <button onclick="trackButton(3);">Button 3</button> +<pre> var buttons = document.querySelectorAll('button'); + for (var i = 0; i < buttons.length; i++) { + buttons[i].addEventListener('click', trackButtonClick); + } </pre> <p> |