Externe inhoud

Het beveiligingsmodel van Chrome Apps staat externe inhoud in iframes en het gebruik van inline scripting en eval() niet toe. U kunt deze beperkingen negeren, maar uw externe inhoud moet worden geïsoleerd van de app.

Geïsoleerde inhoud heeft geen directe toegang tot de gegevens van de app of een van de API's. Gebruik cross-origin XMLHttpRequests en post-messaging om te communiceren tussen de evenementpagina en de sandbox-inhoud en indirect toegang te krijgen tot de API's.

Verwijzen naar externe bronnen

Het Content Security Policy dat door apps wordt gebruikt, staat het gebruik van veel soorten externe URL's niet toe, zodat u niet rechtstreeks vanaf een app-pagina naar externe afbeeldingen, stylesheets of lettertypen kunt verwijzen. In plaats daarvan kunt u cross-origin XMLHttpRequests gebruiken om deze bronnen op te halen en ze vervolgens via blob: URL's aan te bieden.

Duidelijke eis

Om cross-origin XMLHttpRequests te kunnen uitvoeren, moet u een machtiging toevoegen voor de host van de externe URL:

"permissions": [
    "...",
    "https://supersweetdomainbutnotcspfriendly.com/"
  ]

Cross-origin XMLHttpRequest

Haal de externe URL op in de app en geef de inhoud ervan weer als een blob: URL:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://supersweetdomainbutnotcspfriendly.com/image.png', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
  var img = document.createElement('img');
  img.src = window.URL.createObjectURL(this.response);
  document.body.appendChild(img);
};

xhr.send();

Mogelijk wilt u deze bronnen lokaal opslaan , zodat ze offline beschikbaar zijn.

Externe webpagina's insluiten

Met de webview tag kunt u externe webinhoud in uw app insluiten, bijvoorbeeld een webpagina. Het vervangt iframes die verwijzen naar externe URL's, die zijn uitgeschakeld in Chrome-apps. In tegenstelling tot iframes wordt de webview tag in een afzonderlijk proces uitgevoerd. Dit betekent dat een exploit erin nog steeds geïsoleerd zal zijn en geen verhoogde rechten kan verkrijgen. Omdat de opslag (cookies, enz.) bovendien geïsoleerd is van de app, heeft de webinhoud geen enkele mogelijkheid om toegang te krijgen tot de gegevens van de app.

Webview-element toevoegen

Uw webview element moet de URL naar de broninhoud bevatten en de afmetingen ervan specificeren.

<webview src="http://news.google.com/" width="640" height="480"></webview>

Eigenschappen bijwerken

Als u de eigenschappen src , width en height van een webview tag dynamisch wilt wijzigen, kunt u deze eigenschappen rechtstreeks op het JavaScript-object instellen of de DOM-functie setAttribute gebruiken.

document.querySelector('#mywebview').src =
    'http://blog.chromium.org/';
// or
document.querySelector('#mywebview').setAttribute(
    'src', 'http://blog.chromium.org/');

Lokale inhoud in de sandbox

Met sandboxing kunnen specifieke pagina's worden weergegeven in een sandbox-, unieke oorsprong. Deze pagina's zijn dan vrijgesteld van hun Content Security Policy. Pagina's in een sandbox kunnen iframes, inline scripting en eval() gebruiken. Bekijk de manifestveldbeschrijving voor sandbox .

Het is echter een afweging: pagina's in een sandbox kunnen de chrome.* API's niet gebruiken. Als je dingen als eval() moet doen, volg dan deze route om vrijgesteld te worden van CSP, maar je zult de coole nieuwe dingen niet kunnen gebruiken.

Gebruik inline-scripts in de sandbox

Hier is een voorbeeld van een sandbox-pagina die een inline script en eval() gebruikt:

<html>
  <body>
    <h1>Woot</h1>
    <script>
      eval('console.log(\'I am an eval-ed inline script.\')');
    </script>
  </body>
</html>

Sandbox opnemen in manifest

U moet het sandbox in het manifest opnemen en de app-pagina's vermelden die in een sandbox moeten worden weergegeven:

"sandbox": {
  "pages": ["sandboxed.html"]
}

Een sandboxpagina openen in een venster

Net als bij andere app-pagina's kunt u een venster maken waarin de pagina in de sandbox wordt geopend. Hier is een voorbeeld waarin twee vensters worden gemaakt: één voor het hoofdvenster van de app dat niet in de sandbox is geplaatst, en één voor de pagina in de sandbox:

chrome.app.runtime.onLaunched.addListener(function() {
  chrome.app.window.create('window.html', {
    'bounds': {
      'width': 400,
      'height': 400,
      'left': 0,
      'top': 0
    }
  });

  chrome.app.window.create('sandboxed.html', {
    'bounds': {
      'width': 400,
      'height': 400,
      'left': 400,
      'top': 0
    }
  });
});

Een sandboxpagina insluiten in een app-pagina

Pagina's in een sandbox kunnen ook worden ingesloten in een andere app-pagina met behulp van een iframe :

<!DOCTYPE html>
<html>
<head>
</head>
  <body>
    <p>I am normal app window.</p>

    <iframe src="sandboxed.html" width="300" height="200"></iframe>
  </body>
</html>

Berichten verzenden naar pagina's in de sandbox

Het verzenden van een bericht bestaat uit twee delen: u moet een bericht plaatsen vanaf de afzenderpagina/-venster, en luisteren naar berichten op de ontvangende pagina/venster.

Bericht plaatsen

U kunt postMessage gebruiken om te communiceren tussen uw app en inhoud in de sandbox. Hier is een voorbeeld van een achtergrondscript dat een bericht plaatst op de sandbox-pagina die wordt geopend:

var myWin = null;

chrome.app.runtime.onLaunched.addListener(function() {
  chrome.app.window.create('sandboxed.html', {
    'bounds': {
      'width': 400,
      'height': 400
    }
  }, function(win) {
       myWin = win;
       myWin.contentWindow.postMessage('Just wanted to say hey.', '*');
     });
});

Over het algemeen wilt u op internet de exacte herkomst opgeven vanwaar het bericht wordt verzonden. Chrome-apps hebben geen toegang tot de unieke oorsprong van content in een sandbox. U kunt dus alleen alle bronnen op de toelatingslijst zetten als acceptabele bronnen ('*'). Aan de ontvangende kant wilt u doorgaans de herkomst controleren; maar aangezien er Chrome Apps-inhoud aanwezig is, is dit niet nodig. Zie window.postMessage voor meer informatie.

Luister naar bericht en antwoord

Hier is een voorbeeld van een berichtontvanger die wordt toegevoegd aan uw sandboxpagina:

var messageHandler = function(event) {
  console.log('Background script says hello.', event.data);

  // Send a reply
  event.source.postMessage(
      {'reply': 'Sandbox received: ' + event.data}, event.origin);
};

window.addEventListener('message', messageHandler);

Bekijk het sandbox- voorbeeld voor meer informatie.