Home | History | Annotate | Download | only in static
      1 <div id="pageData-name" class="pageData">Cross-Origin XMLHttpRequest</div>
      2 
      3 <!-- BEGIN AUTHORED CONTENT -->
      4 <p id="classSummary">
      5 Regular web pages can use the
      6 <a href="http://www.w3.org/TR/XMLHttpRequest/">XMLHttpRequest</a>
      7 object to send and receive data from remote servers,
      8 but they're limited by the
      9 <a href="http://en.wikipedia.org/wiki/Same_origin_policy">same origin policy</a>.
     10 Extensions aren't so limited.
     11 An extension can talk to remote servers outside of its origin,
     12 as long as it first requests cross-origin permissions.</p>
     13 
     14 <p class="note">
     15 <b>Note:</b>
     16 Content scripts can't directly make cross-origin requests.
     17 However, a content script can
     18 send a message to its parent extension
     19 that asks the extension to make a cross-origin request.
     20 For an example of this technique, see the
     21 <a href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/howto/contentscript_xhr">contentscript_xhr example</a>.
     22 </p>
     23 
     24 <h2 id="extension-origin">Extension origin</h2>
     25 <p>Each running extension exists within its own separate security origin. Without
     26 requesting additional privileges, the extension can use
     27 XMLHttpRequest to get resources within its installation. For example, if
     28 an extension contains a JSON configuration file called <code>config.json</code>,
     29 in a <code>config_resources</code> folder, the extension can retrieve the file's contents like
     30 this:</p>
     31 
     32 <pre>
     33 var xhr = new XMLHttpRequest();
     34 xhr.onreadystatechange = handleStateChange; // Implemented elsewhere.
     35 xhr.open("GET", chrome.extension.getURL('/config_resources/config.json'), true);
     36 xhr.send();
     37 </pre>
     38 
     39 <p>If the extension attempts to use a security origin other than itself,
     40 say http://www.google.com,
     41 the browser disallows it
     42 unless the extension has requested the appropriate cross-origin permissions.
     43 </p>
     44 
     45 <h2 id="requesting-permission">Requesting cross-origin permissions</h2>
     46 
     47 <p>By adding hosts or host match patterns (or both) to the
     48 <a href="manifest.html#permissions">permissions</a> section of the
     49 <a href="manifest.html">manifest</a> file, the extension can request access to
     50 remote servers outside of its origin.</p>
     51 
     52 <pre>{
     53   "name": "My extension",
     54   ...
     55   <b>"permissions": [
     56     "http://www.google.com/"
     57   ]</b>,
     58   ...
     59 }</pre>
     60 
     61 <p>Cross-origin permission values can be fully qualified host names,
     62 like these:</p>
     63 
     64 <ul>
     65   <li> "http://www.google.com/" </li>
     66   <li> "http://www.gmail.com/" </li>
     67 </ul>
     68 
     69 <p>Or they can be match patterns, like these:</p>
     70 
     71 <ul>
     72   <li> "http://*.google.com/" </li>
     73   <li> "http://*/" </li>
     74 </ul>
     75 
     76 <p>
     77 A match pattern of "http://*/" allows HTTP access to all reachable domains.
     78 Note that here,
     79 match patterns are similar to <a href="match_patterns.html">content script
     80 match patterns</a>,
     81 but any path information following the host is ignored.</p>
     82 
     83 <p>Also note that access is granted both by host and by scheme. If an extension
     84 wants both secure and non-secure HTTP access to a given host or set
     85 of hosts, it must declare the permissions separately:</p>
     86 
     87 <pre>"permissions": [
     88   "http://www.google.com/",
     89   "https://www.google.com/"
     90 ]
     91 </pre>
     92 
     93 <h2 id="security-considerations">Security considerations</h2>
     94 
     95 <p>
     96 When using resources retrieved via XMLHttpRequest, your background page should
     97 be careful not to fall victim to <a
     98 href="http://en.wikipedia.org/wiki/Cross-site_scripting">cross-site
     99 scripting</a>.  Specifically, avoid using dangerous APIs such as the below:
    100 </p>
    101 <pre>background.html
    102 ===============
    103 var xhr = new XMLHttpRequest();
    104 xhr.open("GET", "http://api.example.com/data.json", true);
    105 xhr.onreadystatechange = function() {
    106   if (xhr.readyState == 4) {
    107     // WARNING! Might be evaluating an evil script!
    108     var resp = eval("(" + xhr.responseText + ")");
    109     ...
    110   }
    111 }
    112 xhr.send();
    113 
    114 background.html
    115 ===============
    116 var xhr = new XMLHttpRequest();
    117 xhr.open("GET", "http://api.example.com/data.json", true);
    118 xhr.onreadystatechange = function() {
    119   if (xhr.readyState == 4) {
    120     // WARNING! Might be injecting a malicious script!
    121     document.getElementById("resp").innerHTML = xhr.responseText;
    122     ...
    123   }
    124 }
    125 xhr.send();
    126 </pre>
    127 <p>
    128 Instead, prefer safer APIs that do not run scripts:
    129 </p>
    130 <pre>background.html
    131 ===============
    132 var xhr = new XMLHttpRequest();
    133 xhr.open("GET", "http://api.example.com/data.json", true);
    134 xhr.onreadystatechange = function() {
    135   if (xhr.readyState == 4) {
    136     // JSON.parse does not evaluate the attacker's scripts.
    137     var resp = JSON.parse(xhr.responseText);
    138   }
    139 }
    140 xhr.send();
    141 
    142 background.html
    143 ===============
    144 var xhr = new XMLHttpRequest();
    145 xhr.open("GET", "http://api.example.com/data.json", true);
    146 xhr.onreadystatechange = function() {
    147   if (xhr.readyState == 4) {
    148     // innerText does not let the attacker inject HTML elements.
    149     document.getElementById("resp").innerText = xhr.responseText;
    150   }
    151 }
    152 xhr.send();
    153 </pre>
    154 <p>
    155 Additionally, be especially careful of resource retrieved via HTTP.  If your
    156 extension is used on a hostile network, an network attacker (aka a <a
    157 href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack">"man-in-the-middle"</a>)
    158 could modify the response and, potentially, attack your extension.  Instead,
    159 prefer HTTPS whenever possible.
    160 </p>
    161 
    162 <!-- END AUTHORED CONTENT -->
    163