Site-isolatie voor webontwikkelaars

In Chrome 67 op de desktop is standaard een nieuwe functie genaamd Site Isolatie ingeschakeld . In dit artikel wordt uitgelegd waar het bij site-isolatie om gaat, waarom het nodig is en waarom webontwikkelaars zich hiervan bewust moeten zijn.

Wat is locatie-isolatie?

Het internet is onder andere bedoeld voor het bekijken van kattenvideo's en het beheren van portemonnees voor cryptovaluta, maar je wilt niet dat fluffycats.example toegang heeft tot je kostbare cryptomunten! Gelukkig hebben websites doorgaans geen toegang tot elkaars gegevens in de browser dankzij het Same-Origin Policy. Toch kunnen kwaadwillende websites proberen dit beleid te omzeilen door andere websites aan te vallen, en af ​​en toe worden er beveiligingsfouten aangetroffen in de browsercode die het Same-Origin-beleid afdwingt. Het Chrome-team streeft ernaar dergelijke bugs zo snel mogelijk op te lossen.

Site-isolatie is een beveiligingsfunctie in Chrome die een extra verdedigingslinie biedt om ervoor te zorgen dat dergelijke aanvallen minder kans van slagen hebben. Het zorgt ervoor dat pagina's van verschillende websites altijd in verschillende processen worden geplaatst, die elk in een sandbox draaien die beperkt wat het proces mag doen. Het blokkeert ook het proces om bepaalde soorten gevoelige gegevens van andere sites te ontvangen. Als gevolg hiervan is het met Site Isolation veel moeilijker voor een kwaadwillende website om speculatieve zijkanaalaanvallen zoals Spectre te gebruiken om gegevens van andere sites te stelen. Naarmate het Chrome-team aanvullende handhavingsmaatregelen voltooit, kan site-isolatie ook helpen, zelfs wanneer de pagina van een aanvaller tijdens zijn eigen proces enkele regels kan overtreden.

Site-isolatie maakt het feitelijk moeilijker voor niet-vertrouwde websites om toegang te krijgen tot informatie uit uw accounts op andere websites of deze te stelen. Het biedt extra bescherming tegen verschillende soorten beveiligingsbugs, zoals de recente Meltdown- en Spectre side-channel-aanvallen .

Zie ons artikel op de Google Security-blog voor meer informatie over site-isolatie.

Cross-Originele leesblokkering

Zelfs als alle cross-site pagina's in afzonderlijke processen worden geplaatst, kunnen pagina's nog steeds op legitieme wijze bepaalde cross-site subbronnen opvragen, zoals afbeeldingen en JavaScript. Een kwaadwillende webpagina kan een <img> -element gebruiken om een ​​JSON-bestand met gevoelige gegevens te laden, zoals uw banksaldo:

<img src="https://your-bank.example/balance.json" />
<!-- Note: the attacker refused to add an `alt` attribute, for extra evil points. -->

Zonder site-isolatie zou de inhoud van het JSON-bestand in het geheugen van het rendererproces terechtkomen, waarna de renderer merkt dat het geen geldig afbeeldingsformaat is en geen afbeelding rendert. Maar de aanvaller zou dan een kwetsbaarheid als Spectre kunnen misbruiken om mogelijk dat deel van het geheugen te lezen.

In plaats van <img> te gebruiken, kan de aanvaller ook <script> gebruiken om de gevoelige gegevens in het geheugen vast te leggen:

<script src="https://your-bank.example/balance.json"></script>

Cross-Origin Read Blocking, of CORB, is een nieuwe beveiligingsfunctie die voorkomt dat de inhoud van balance.json ooit in het geheugen van het procesgeheugen van de renderer terechtkomt, op basis van het MIME-type.

Laten we eens kijken hoe CORB werkt. Een website kan twee soorten bronnen van een server opvragen:

  1. gegevensbronnen zoals HTML-, XML- of JSON-documenten
  2. mediabronnen zoals afbeeldingen, JavaScript, CSS of lettertypen

Een website kan gegevensbronnen ontvangen van zijn eigen oorsprong of van andere oorsprong met tolerante CORS- headers zoals Access-Control-Allow-Origin: * . Aan de andere kant kunnen mediabronnen van elke oorsprong worden opgenomen, zelfs zonder tolerante CORS-headers.

CORB voorkomt dat het rendererproces een cross-origin gegevensbron ontvangt (dat wil zeggen HTML, XML of JSON) als:

  • de bron heeft een X-Content-Type-Options: nosniff -header
  • CORS staat niet expliciet toegang tot de bron toe

Als de cross-origin-gegevensbron niet de header X-Content-Type-Options: nosniff heeft, probeert CORB de antwoordtekst te snuffelen om te bepalen of het HTML, XML of JSON is. Dit is nodig omdat sommige webservers verkeerd zijn geconfigureerd en afbeeldingen bijvoorbeeld als text/html weergeven.

Gegevensbronnen die door het CORB-beleid worden geblokkeerd, worden als leeg aan het proces gepresenteerd, hoewel het verzoek nog steeds op de achtergrond plaatsvindt. Als gevolg hiervan heeft een kwaadwillende webpagina moeite om cross-site gegevens in het proces te betrekken om te stelen.

Voor optimale veiligheid en om te profiteren van CORB raden wij het volgende aan:

  • Markeer antwoorden met de juiste Content-Type header. (HTML-bronnen moeten bijvoorbeeld worden weergegeven als text/html , JSON-bronnen met een JSON MIME-type en XML-bronnen met een XML MIME-type ).
  • Meld u af voor snuiven door de header X-Content-Type-Options: nosniff te gebruiken. Zonder deze header voert Chrome een snelle inhoudsanalyse uit om te proberen te bevestigen dat het type correct is, maar aangezien dit de fout maakt om reacties door te laten om te voorkomen dat zaken als JavaScript-bestanden worden geblokkeerd, kunt u beter bevestigend het juiste doen jezelf.

Raadpleeg voor meer details het CORB-artikel voor webontwikkelaars of onze uitgebreide CORB-uitleg .

Waarom zouden webontwikkelaars zich zorgen maken over site-isolatie?

Site-isolatie is voor het grootste deel een browserfunctie achter de schermen die niet rechtstreeks zichtbaar is voor webontwikkelaars. Er is bijvoorbeeld geen nieuwe webgebaseerde API om te leren. Over het algemeen zouden webpagina's het verschil niet moeten kunnen zien als ze met of zonder Site Isolation worden uitgevoerd.

Er zijn echter enkele uitzonderingen op deze regel. Het inschakelen van Site-isolatie heeft enkele subtiele bijwerkingen die van invloed kunnen zijn op uw website. We houden een lijst bij met bekende problemen met site-isolatie , en we gaan hieronder dieper in op de belangrijkste.

De lay-out van de volledige pagina is niet langer synchroon

Met Site Isolation is de lay-out van de volledige pagina niet langer gegarandeerd synchroon, omdat de frames van een pagina nu over meerdere processen kunnen worden verspreid. Dit kan van invloed zijn op pagina's als ze ervan uitgaan dat een lay-outwijziging onmiddellijk wordt doorgevoerd naar alle frames op de pagina.

Laten we als voorbeeld een website nemen met de naam fluffykittens.example die communiceert met een sociale widget die wordt gehost op social-widget.example :

<!-- https://fluffykittens.example/ -->
<iframe src="https://social-widget.example/" width="123"></iframe>
<script>
  const iframe = document.querySelector('iframe');
  iframe.width = 456;
  iframe.contentWindow.postMessage(
    // The message to send:
    'Meow!',
    // The target origin:
    'https://social-widget.example'
  );
</script>

In eerste instantie is de breedte van <iframe> van de sociale widget 123 pixels. Maar dan verandert de FluffyKittens-pagina de breedte naar 456 pixels (wat de lay-out activeert) en stuurt een bericht naar de sociale widget, die de volgende code bevat:

<!-- https://social-widget.example/ -->
<script>
  self.onmessage = () => {
    console.log(document.documentElement.clientWidth);
  };
</script>

Telkens wanneer de sociale widget een bericht ontvangt via de postMessage API, registreert deze de breedte van zijn hoofdelement <html> .

Welke breedtewaarde wordt geregistreerd? Voordat Chrome Site-isolatie inschakelde, was het antwoord 456 . Toegang tot document.documentElement.clientWidth forceert de lay-out, die vroeger synchroon was voordat Chrome Site-isolatie inschakelde. Als Site-isolatie is ingeschakeld, gebeurt de herindeling van de cross-origin sociale widget nu echter asynchroon in een afzonderlijk proces. Het antwoord kan dus nu ook 123 zijn, dat wil zeggen de oude width .

Als een pagina de grootte van een cross-origin <iframe> verandert en er vervolgens een postMessage naartoe stuurt, weet het ontvangende frame met Site Isolation mogelijk nog niet de nieuwe grootte wanneer het bericht wordt ontvangen. Meer in het algemeen kan dit ertoe leiden dat pagina's kapot gaan als ze ervan uitgaan dat een wijziging in de lay-out onmiddellijk wordt doorgevoerd in alle frames op de pagina.

In dit specifieke voorbeeld zou een robuustere oplossing de width in het bovenliggende frame instellen en die verandering in het <iframe> detecteren door te luisteren naar een resize gebeurtenis.

Unload-handlers kunnen vaker een time-out krijgen

Wanneer een frame navigeert of sluit, voeren het oude document en alle daarin ingebedde subframedocumenten allemaal hun unload uit. Als de nieuwe navigatie plaatsvindt in hetzelfde rendererproces (bijvoorbeeld voor een navigatie van dezelfde oorsprong), kunnen de unload van het oude document en de subframes ervan willekeurig lang draaien voordat de nieuwe navigatie wordt vastgelegd.

addEventListener('unload', () => {
  doSomethingThatMightTakeALongTime();
});

In deze situatie zijn de unload in alle frames zeer betrouwbaar.

Maar zelfs zonder site-isolatie zijn sommige hoofdframenavigaties cross-process, wat invloed heeft op het gedrag van de ontlaadhandler. Als u bijvoorbeeld van old.example naar new.example navigeert door de URL in de adresbalk te typen, vindt de navigatie new.example plaats in een nieuw proces. De unload-handlers voor old.example en de bijbehorende subframes worden uitgevoerd in het old.example proces op de achtergrond, nadat de new.example pagina is weergegeven, en de oude unload-handlers worden beëindigd als ze niet binnen een bepaalde time-out zijn voltooid . Omdat de ontlaadhandlers mogelijk niet vóór de time-out klaar zijn, is het ontlaadgedrag minder betrouwbaar.

Met Site Isolation worden alle navigaties tussen sites cross-process, zodat documenten van verschillende sites geen proces met elkaar delen. Als gevolg hiervan is de bovenstaande situatie in meer gevallen van toepassing, en hebben unload handlers in <iframe> s vaak het hierboven beschreven achtergrond- en time-outgedrag.

Een ander verschil dat voortvloeit uit Site Isolation is de nieuwe parallelle volgorde van unload handlers: zonder Site Isolation draaien unload handlers in een strikte top-down volgorde over de frames heen. Maar met Site Isolation worden de ontladingshandlers parallel uitgevoerd in verschillende processen.

Dit zijn fundamentele gevolgen van het inschakelen van Site Isolatie. Het Chrome-team werkt waar mogelijk aan het verbeteren van de betrouwbaarheid van losbehandelaars voor veelvoorkomend gebruik. We zijn ook op de hoogte van bugs waarbij subframe-ontlaadhandlers bepaalde functies nog niet kunnen gebruiken en werken aan een oplossing hiervan.

Een belangrijk voorbeeld voor unload handlers is het verzenden van pings aan het einde van de sessie. Dit wordt gewoonlijk als volgt gedaan:

addEventListener('pagehide', () => {
  const image = new Image();
  img.src = '/end-of-session';
});

Een betere aanpak die robuuster is in het licht van deze verandering is om in plaats daarvan navigator.sendBeacon te gebruiken:

addEventListener('pagehide', () => {
  navigator.sendBeacon('/end-of-session');
});

Als u meer controle over het verzoek nodig heeft, kunt u de keepalive optie van de Fetch API gebruiken:

addEventListener('pagehide', () => {
  fetch('/end-of-session', {keepalive: true});
});

Conclusie

Site-isolatie maakt het moeilijker voor niet-vertrouwde websites om toegang te krijgen tot uw accounts op andere websites of deze te stelen, door elke site in zijn eigen proces te isoleren. Als onderdeel daarvan probeert CORB gevoelige gegevensbronnen buiten het rendererproces te houden. Onze bovenstaande aanbevelingen zorgen ervoor dat u het meeste uit deze nieuwe beveiligingsfuncties haalt.

Met dank aan Alex Moshchuk, Charlie Reis, Jason Miller, Nasko Oskov, Philip Walton, Shubhie Panicker en Thomas Steiner voor het lezen van een conceptversie van dit artikel en het geven van hun feedback.