Het verkrijgen van veiligheid en privacy door de cache te partitioneren

Over het algemeen kan caching de prestaties verbeteren door gegevens op te slaan, zodat toekomstige verzoeken om dezelfde gegevens sneller worden afgehandeld. Een in de cache opgeslagen bron van het netwerk kan bijvoorbeeld een retourtje naar de server vermijden. Een in de cache opgeslagen rekenresultaat kan de tijd weglaten om dezelfde berekening uit te voeren.

In Chrome wordt het cachemechanisme op verschillende manieren gebruikt en HTTP Cache is daar een voorbeeld van.

Hoe de HTTP-cache van Chrome momenteel werkt

Vanaf versie 85 slaat Chrome bronnen op die van het netwerk zijn opgehaald, waarbij de respectievelijke bron-URL's als cachesleutel worden gebruikt. (Een cachesleutel wordt gebruikt om een ​​in de cache opgeslagen bron te identificeren.)

Het volgende voorbeeld illustreert hoe een enkele afbeelding in de cache wordt opgeslagen en in drie verschillende contexten wordt behandeld:

Cachesleutel: https://x.example/doge.png
Cachesleutel : { https://x.example/doge.png }

Een gebruiker bezoekt een pagina ( https://a.example ) die om een ​​afbeelding vraagt ​​( https://x.example/doge.png ). De afbeelding wordt opgevraagd bij het netwerk en in de cache opgeslagen met https://x.example/doge.png als sleutel.

Cachesleutel: https://x.example/doge.png
Cachesleutel : { https://x.example/doge.png }

Dezelfde gebruiker bezoekt een andere pagina ( https://b.example ), die om dezelfde afbeelding vraagt ​​( https://x.example/doge.png ). De browser controleert de HTTP-cache om te zien of deze bron al in de cache is opgeslagen, waarbij de afbeeldings-URL als sleutel wordt gebruikt. De browser vindt een overeenkomst in zijn cache en gebruikt daarom de in de cache opgeslagen versie van de bron.

Cachesleutel: https://x.example/doge.png
Cachesleutel : { https://x.example/doge.png }

Het maakt niet uit of de afbeelding vanuit een iframe wordt geladen. Als de gebruiker een andere website bezoekt ( https://c.example ) met een iframe ( https://d.example ) en het iframe vraagt ​​om dezelfde afbeelding ( https://x.example/doge.png ), zal de browser kan de afbeelding nog steeds uit de cache laden omdat de cachesleutel op alle pagina's hetzelfde is.

Vanuit prestatieperspectief werkt dit mechanisme al lange tijd goed. De tijd die een website nodig heeft om op HTTP-verzoeken te reageren, kan echter uitwijzen dat de browser in het verleden dezelfde bron heeft gebruikt, waardoor de browser wordt blootgesteld aan beveiligings- en privacyaanvallen, zoals de volgende:

  • Detecteren of een gebruiker een specifieke site heeft bezocht : een tegenstander kan de browsegeschiedenis van een gebruiker detecteren door te controleren of de cache een bron bevat die specifiek kan zijn voor een bepaalde site of een cohort van sites.
  • Cross-site search-aanval : een tegenstander kan detecteren of een willekeurige reeks in de zoekresultaten van de gebruiker voorkomt door te controleren of een afbeelding 'geen zoekresultaten' die door een bepaalde website wordt gebruikt, zich in de cache van de browser bevindt.
  • Cross-site tracking : De cache kan worden gebruikt om cookie-achtige identificatiegegevens op te slaan als een cross-site tracking-mechanisme.

Om deze risico's te beperken, verdeelt Chrome de HTTP-cache vanaf Chrome 86.

Welke invloed heeft cachepartitionering op de HTTP-cache van Chrome?

Met cachepartitionering worden in de cache opgeslagen bronnen gecodeerd met behulp van een nieuwe "Network Isolation Key" naast de bron-URL. De netwerkisolatiesleutel bestaat uit de site op het hoogste niveau en de site met het huidige frame.

Kijk nog eens naar het vorige voorbeeld om te zien hoe cachepartitionering in verschillende contexten werkt:

Cachesleutel { https://a.example, https://a.example, https://x.example/doge.png}
Cachesleutel : { https://a.example , https://a.example , https://x.example/doge.png }

Een gebruiker bezoekt een pagina ( https://a.example ) die om een ​​afbeelding vraagt ​​( https://x.example/doge.png ). In dit geval wordt de afbeelding opgevraagd bij het netwerk en in de cache opgeslagen met behulp van een tuple bestaande uit https://a.example (de site op het hoogste niveau), https://a.example (de site met het huidige frame) en https://x.example/doge.png (de bron-URL) als sleutel. (Houd er rekening mee dat wanneer het bronverzoek afkomstig is van het hoogste niveau-frame, de site op het hoogste niveau en de huidige framesite in de netwerkisolatiesleutel hetzelfde zijn.)

Cachesleutel { https://a.example, https://a.example, https://x.example/doge.png}
Cachesleutel : { https://b.example , https://b.example , https://x.example/doge.png }

Dezelfde gebruiker bezoekt een andere pagina ( https://b.example ) die om dezelfde afbeelding vraagt ​​( https://x.example/doge.png ). Hoewel dezelfde afbeelding in het vorige voorbeeld is geladen, zal het geen cachetreffer zijn, omdat de sleutel niet overeenkomt.

De afbeelding wordt opgevraagd bij het netwerk en in de cache opgeslagen met behulp van een tupel die bestaat uit https://b.example , https://b.example en https://x.example/doge.png als sleutel.

Cachesleutel { https://a.example, https://a.example, https://x.example/doge.png}
Cachesleutel : { https://a.example , https://a.example , https://x.example/doge.png }

Nu komt de gebruiker terug naar https://a.example , maar deze keer is de afbeelding ( https://x.example/doge.png ) ingebed in een iframe. In dit geval is de sleutel een tupel met daarin https://a.example , https://a.example en https://x.example/doge.png en er vindt een cachehit plaats. (Merk op dat wanneer de site op het hoogste niveau en het iframe dezelfde site zijn, de bron die in de cache met het frame op het hoogste niveau is opgeslagen, kan worden gebruikt.

Cachesleutel { https://a.example, https://a.example, https://x.example/doge.png}
Cachesleutel : { https://a.example , https://c.example , https://x.example/doge.png }

De gebruiker is terug op https://a.example , maar deze keer wordt de afbeelding gehost in een iframe van https://c.example .

In dit geval wordt de afbeelding gedownload van het netwerk omdat er geen bron in de cache aanwezig is die overeenkomt met de sleutel bestaande uit https://a.example , https://c.example en https://x.example/doge.png .

Cachesleutel { https://a.example, https://a.example, https://x.example/doge.png}
Cachesleutel : { https://a.example , https://c.example , https://x.example/doge.png }

Wat als het domein een subdomein of een poortnummer bevat? De gebruiker bezoekt https://subdomain.a.example , waar een iframe ( https://c.example:8080 ) is ingesloten, dat om de afbeelding vraagt.

Omdat de sleutel wordt aangemaakt op basis van "scheme://eTLD+1", worden subdomeinen en poortnummers genegeerd. Er treedt dus een cachetreffer op.

Cachesleutel { https://a.example, https://a.example, https://x.example/doge.png}
Cachesleutel : { https://a.example , https://c.example , https://x.example/doge.png }

Wat moet ik doen als het iframe meerdere keren is genest? De gebruiker bezoekt https://a.example , dat een iframe insluit ( https://b.example ), dat nog een ander iframe insluit ( https://c.example ), dat uiteindelijk om de afbeelding vraagt.

Omdat de sleutel wordt overgenomen uit het topframe ( https://a.example ) en het onmiddellijke frame dat de bron laadt ( https://c.example ), vindt er een cachehit plaats.

Veelgestelde vragen

Is het al ingeschakeld in mijn Chrome? Hoe kan ik dit controleren?

De functie wordt eind 2020 uitgerold. Controleren of uw Chrome-instantie deze al ondersteunt:

  1. Open chrome://net-export/ en druk op Start loggen naar schijf .
  2. Geef op waar u het logbestand op uw computer wilt opslaan.
  3. Surf een minuutje op internet in Chrome.
  4. Ga terug naar chrome://net-export/ en druk op Stop Logging .
  5. Ga naar https://netlog-viewer.appspot.com/#import .
  6. Druk op Bestand kiezen en geef het logbestand door dat u hebt opgeslagen.

U ziet de uitvoer van het logbestand.

Zoek op dezelfde pagina SplitCacheByNetworkIsolationKey . Als dit wordt gevolgd door Experiment_[****] , is HTTP-cachepartitionering ingeschakeld op uw Chrome. Als het wordt gevolgd door Control_[****] of Default_[****] , is het niet ingeschakeld.

Hoe kan ik HTTP-cachepartitionering testen in mijn Chrome?

Om HTTP-cache-partitionering op uw Chrome te testen, moet u Chrome starten met een opdrachtregelvlag: --enable-features=SplitCacheByNetworkIsolationKey . Volg de instructies bij Chromium uitvoeren met vlaggen om te leren hoe u Chrome kunt starten met een opdrachtregelvlag op uw platform.

Moet ik als webontwikkelaar actie ondernemen als reactie op deze wijziging?

Dit is geen baanbrekende wijziging, maar kan voor sommige webservices prestatieoverwegingen met zich meebrengen.

Degenen die bijvoorbeeld grote hoeveelheden goed cachebare bronnen op veel sites aanbieden (zoals lettertypen en populaire scripts), kunnen een toename van hun verkeer zien. Ook kunnen degenen die dergelijke diensten gebruiken er in toenemende mate afhankelijk van zijn.

(Er is een voorstel om gedeelde bibliotheken op een privacybeschermende manier in te schakelen, genaamd Web Shared Libraries ( presentatievideo ), maar dit wordt nog steeds overwogen.)

Wat is de impact van deze gedragsverandering?

Het totale aantal gemiste caches neemt toe met ongeveer 3,6%, de wijzigingen aan de FCP (First Contentful Paint) zijn bescheiden (~0,3%) en het totale aantal bytes dat vanuit het netwerk wordt geladen, neemt met ongeveer 4% toe. U kunt meer leren over de impact op de prestaties in de uitleg over HTTP-cachepartitionering .

Is dit gestandaardiseerd? Gedragen andere browsers zich anders?

"HTTP-cachepartities" is gestandaardiseerd in de ophaalspecificatie, hoewel browsers zich anders gedragen:

Hoe wordt het ophalen van werknemers behandeld?

Toegewijde werknemers gebruiken dezelfde sleutel als hun huidige frame. Servicemedewerkers en gedeelde medewerkers zijn ingewikkelder omdat ze over meerdere sites op het hoogste niveau kunnen worden gedeeld. De oplossing voor hen wordt momenteel besproken.

Bronnen