Mit User-Agent-Client-Hints den Datenschutz und die Nutzerfreundlichkeit für Entwickler verbessern

User-Agent-Client-Hinweise sind eine neue Erweiterung der Client Hints API, mit der Entwickler auf datenschutzfreundliche und ergonomische Weise auf Informationen zum Browser eines Nutzers zugreifen können.

Mit Client-Hints können Entwickler Informationen zum Gerät oder zu den Bedingungen des Nutzers aktiv anfordern, anstatt sie aus dem User-Agent-String (UA-String) zu parsen. Die Bereitstellung dieser alternativen Route ist der erste Schritt zur Reduzierung der Detailgenauigkeit von User-Agent-Strings.

Hier erfahren Sie, wie Sie Ihre vorhandenen Funktionen, die auf dem Parsen des User-Agent-Strings basieren, aktualisieren, um stattdessen Client-Hinweise in User-Agent-Headern zu verwenden.

Hintergrund

Wenn Webbrowser Anfragen senden, enthalten diese Informationen zum Browser und seiner Umgebung, damit Server Analysen aktivieren und die Antwort anpassen können. Dieser wurde bereits 1996 (RFC 1945 für HTTP/1.0) definiert. Dort finden Sie die ursprüngliche Definition für den User-Agent-String mit einem Beispiel:

User-Agent: CERN-LineMode/2.15 libwww/2.17b3

Mit diesem Header sollten in der Reihenfolge ihrer Bedeutung das Produkt (z.B. Browser oder Bibliothek) und ein Kommentar (z.B. Version) angegeben werden.

Der Status des User-Agent-Strings

In den Jahrzehnten, die vergangen sind, wurden diesem String eine Vielzahl zusätzlicher Details über den Client hinzugefügt, der die Anfrage stellt. Außerdem wurde er aufgrund der Abwärtskompatibilität mit unnötigen Informationen überladen. Das sehen wir, wenn wir uns den aktuellen User-Agent-String von Chrome ansehen:

Mozilla/5.0 (Linux; Android 10; Pixel 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4076.0 Mobile Safari/537.36

Der obige String enthält Informationen zum Betriebssystem und zur Version des Nutzers, zum Gerätemodell, zur Marke und vollständigen Version des Browsers sowie ausreichend Hinweise, um daraus abzuleiten, dass es sich um einen mobilen Browser handelt. Außerdem enthält er aus historischen Gründen Verweise auf andere Browser.

Durch die Kombination dieser Parameter mit der großen Vielfalt möglicher Werte kann der User-Agent-String genügend Informationen enthalten, um einzelne Nutzer eindeutig identifizieren zu können.

Der User-Agent-String ermöglicht viele legitime Anwendungsfälle und bietet Entwicklern und Websiteinhabern einen wichtigen Zweck. Es ist jedoch auch wichtig, dass die Daten der Nutzer vor verdeckten Tracking-Methoden geschützt sind. Das Senden von UA-Informationen standardmäßig widerspricht diesem Ziel.

Auch die Webkompatibilität muss verbessert werden, wenn es um den User-Agent-String geht. Da sie unstrukturiert ist, ist das Parsen unnötig kompliziert. Das ist oft die Ursache für Fehler und Probleme mit der Websitekompatibilität, die Nutzern schaden. Diese Probleme beeinträchtigen auch Nutzer weniger gängiger Browser überproportional, da Websites möglicherweise nicht auf ihre Konfiguration getestet wurden.

Neue User-Agent-Client-Hints

User-Agent-Client-Hints ermöglichen den Zugriff auf dieselben Informationen, aber auf datenschutzfreundlichere Weise. So können Browser schließlich die Standardeinstellung des User-Agent-Strings, bei der alles übertragen wird, reduzieren. Client-Hinweise erzwingen ein Modell, bei dem der Server den Browser nach einem Satz von Daten über den Client (den Hinweisen) fragen muss und der Browser seine eigenen Richtlinien oder Nutzerkonfigurationen anwendet, um zu bestimmen, welche Daten zurückgegeben werden. Das bedeutet, dass der Zugriff jetzt explizit und prüfbar verwaltet wird, anstatt standardmäßig alle User-Agent-Informationen bereitzustellen. Entwickler profitieren außerdem von einer einfacheren API – keine regulären Ausdrücke mehr!

Die aktuellen Client-Hinweise beschreiben hauptsächlich die Anzeige- und Verbindungsfunktionen des Browsers. Weitere Informationen finden Sie unter Ressourcenauswahl mit Clienthinweisen automatisieren. Im Folgenden erhalten Sie eine kurze Zusammenfassung des Vorgangs.

Der Server fragt über einen Header nach bestimmten Clienthinweisen:

⬇️ Antwort vom Server

Accept-CH: Viewport-Width, Width

Oder ein Meta-Tag:

<meta http-equiv="Accept-CH" content="Viewport-Width, Width" />

Der Browser kann dann in nachfolgenden Anfragen die folgenden Header zurücksenden:

⬆️ Folgeanfrage

Viewport-Width: 460
Width: 230

Der Server kann seine Antworten variieren, z. B. indem er Bilder mit einer geeigneten Auflösung bereitstellt.

Mit User-Agent-Clienthinweisen wird der Bereich der Properties mit dem Präfix Sec-CH-UA erweitert, das über den Serverantwortheader Accept-CH angegeben werden kann. Wenn Sie alle Einzelheiten erfahren möchten, beginnen Sie mit der Erklärung und lesen Sie sich dann das vollständige Angebot durch.

User-Agent-Client-Hints ab Chromium 89

User-Agent-Client-Hints sind in Chrome seit Version 89 standardmäßig aktiviert.

Standardmäßig gibt der Browser die Browsermarke, die Hauptversion, die Plattform und einen Indikator zurück, ob es sich um ein Mobilgerät handelt:

⬆️ Alle Anfragen

Sec-CH-UA: "Chromium";v="93", "Google Chrome";v="93", " Not;A Brand";v="99"
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: "macOS"

User-Agent-Antwort- und -Anfrageheader

⬇️ AntwortAccept-CH
⬆️ Anfrageheader
⬆️ Anfrage
Beispielwert
Beschreibung
Sec-CH-UA "Chromium";v="84",
"Google Chrome";v="84"
Liste der Browsermarken und ihrer wichtigen Version.
Sec-CH-UA-Mobile ?1 Boolescher Wert, der angibt, ob der Browser auf einem Mobilgerät ausgeführt wird (?1 für „wahr“) oder nicht (?0 für „falsch“).
Sec-CH-UA-Full-Version "84.0.4143.2" [Eingestellt] Die vollständige Version für den Browser.
Sec-CH-UA-Full-Version-List "Chromium";v="84.0.4143.2",
"Google Chrome";v="84.0.4143.2"
Liste der Browsermarken und ihrer vollständigen Version.
Sec-CH-UA-Platform "Android" Die Plattform des Geräts, in der Regel das Betriebssystem.
Sec-CH-UA-Platform-Version "10" Die Version der Plattform oder des Betriebssystems.
Sec-CH-UA-Arch "arm" Die zugrunde liegende Architektur des Geräts. Das ist zwar für die Darstellung der Seite nicht relevant, aber die Website kann einen Download anbieten, der standardmäßig im richtigen Format vorliegt.
Sec-CH-UA-Model "Pixel 3" Gerätemodell
Sec-CH-UA-Bitness "64" Die Bitness der zugrunde liegenden Architektur (d.h. die Größe einer Ganzzahl oder Speicheradresse in Bit)

Beispiel-Anzeigenplattform

Ein Beispiel für einen Austausch könnte so aussehen:

⬆️ Erste Anfrage vom Browser
Der Browser fordert die Seite /downloads von der Website an und sendet seinen standardmäßigen einfachen User-Agent.

GET /downloads HTTP/1.1
Host: example.site

Sec-CH-UA: "Chromium";v="93", "Google Chrome";v="93", " Not;A Brand";v="99"
Sec-CH-UA-Mobile: ?1
Sec-CH-UA-Platform: "Android"

⬇️ Antwort vom Server
Der Server sendet die Seite zurück und fragt zusätzlich nach der vollständigen Browserversion und der Plattform.

HTTP/1.1 200 OK
Accept-CH: Sec-CH-UA-Full-Version-List

⬆️ Folgeanfragen
: Der Browser gewährt dem Server Zugriff auf die zusätzlichen Informationen und sendet die zusätzlichen Hinweise in allen nachfolgenden Anfragen zurück.

GET /downloads/app1 HTTP/1.1
Host: example.site

Sec-CH-UA: " Not A;Brand";v="99", "Chromium";v="98", "Google Chrome";v="98"
Sec-CH-UA-Mobile: ?1
Sec-CH-UA-Full-Version-List: " Not A;Brand";v="99.0.0.0", "Chromium";v="98.0.4738.0", "Google Chrome";v="98.0.4738.0"
Sec-CH-UA-Platform: "Android"

JavaScript API

Neben den Headern kann auch in JavaScript über navigator.userAgentData auf den User-Agent zugegriffen werden. Auf die Standardheaderinformationen Sec-CH-UA, Sec-CH-UA-Mobile und Sec-CH-UA-Platform kann über die Attribute brands und mobile zugegriffen werden:

// Log the brand data
console.log(navigator.userAgentData.brands);

// output
[
  {
    brand: 'Chromium',
    version: '93',
  },
  {
    brand: 'Google Chrome',
    version: '93',
  },
  {
    brand: ' Not;A Brand',
    version: '99',
  },
];

// Log the mobile indicator
console.log(navigator.userAgentData.mobile);

// output
false;

// Log the platform value
console.log(navigator.userAgentData.platform);

// output
"macOS";

Auf die zusätzlichen Werte wird über den getHighEntropyValues()-Aufruf zugegriffen. Der Begriff "hohe Entropie" ist ein Verweis auf Informationsentropie, mit anderen Worten: die Menge an Informationen, die diese Werte über den Browser des Nutzers verraten. Wie beim Anfordern der zusätzlichen Header hängt es vom Browser ab, welche Werte zurückgegeben werden.

// Log the full user-agent data
navigator
  .userAgentData.getHighEntropyValues(
    ["architecture", "model", "bitness", "platformVersion",
     "fullVersionList"])
  .then(ua => { console.log(ua) });

// output
{
   "architecture":"x86",
   "bitness":"64",
   "brands":[
      {
         "brand":" Not A;Brand",
         "version":"99"
      },
      {
         "brand":"Chromium",
         "version":"98"
      },
      {
         "brand":"Google Chrome",
         "version":"98"
      }
   ],
   "fullVersionList":[
      {
         "brand":" Not A;Brand",
         "version":"99.0.0.0"
      },
      {
         "brand":"Chromium",
         "version":"98.0.4738.0"
      },
      {
         "brand":"Google Chrome",
         "version":"98.0.4738.0"
      }
   ],
   "mobile":false,
   "model":"",
   "platformVersion":"12.0.1"
}

Demo

Sie können sowohl die Header als auch die JavaScript API auf Ihrem eigenen Gerät unter user-agent-client-hints.glitch.me ausprobieren.

Lebensdauer von Hinweisen und Zurücksetzen

Über den Header Accept-CH angegebene Hinweise werden für die Dauer der Browsersitzung oder so lange gesendet, bis ein anderer Satz von Hinweisen angegeben wird.

Das bedeutet, dass der Server Folgendes sendet:

⬇️ Antwort

Accept-CH: Sec-CH-UA-Full-Version-List

Der Browser sendet dann den Sec-CH-UA-Full-Version-List-Header in allen Anfragen für diese Website, bis der Browser geschlossen wird.

⬆️ Folgeanfragen

Sec-CH-UA-Full-Version-List: " Not A;Brand";v="99.0.0.0", "Chromium";v="98.0.4738.0", "Google Chrome";v="98.0.4738.0"

Wenn jedoch ein anderer Accept-CH-Header empfangen wird, werden die aktuellen vom Browser gesendeten Hinweise vollständig ersetzt.

⬇️ Antwort

Accept-CH: Sec-CH-UA-Bitness

⬆️ Folgeanfragen

Sec-CH-UA-Platform: "64"

Die zuvor angeforderte Sec-CH-UA-Full-Version-List wird nicht gesendet.

Der Accept-CH-Header gibt die vollständigen Hinweise an, die für diese Seite erforderlich sind. Der Browser sendet dann die angegebenen Hinweise für alle untergeordneten Ressourcen auf dieser Seite. Hinweise bleiben zwar bis zur nächsten Navigation erhalten, die Website sollte jedoch nicht davon ausgehen, dass sie ausgeliefert werden.

Du kannst damit auch alle vom Browser gesendeten Hinweise löschen, indem du in der Antwort eine leere Accept-CH sendest. Sie können diesen Hinweis überall hinzufügen, wo der Nutzer die Einstellungen zurücksetzt oder sich von Ihrer Website abmeldet.

Dieses Muster entspricht auch der Funktionsweise von Hinweisen über das <meta http-equiv="Accept-CH" …>-Tag. Die angeforderten Hinweise werden nur bei Anfragen gesendet, die von der Seite initiiert werden, und nicht bei nachfolgender Navigation.

Hinweisbereich und ursprungsübergreifende Anfragen

Standardmäßig werden Clienthinweise nur bei Anfragen vom selben Ursprung gesendet. Wenn Sie also bestimmte Hinweise zu https://example.com anfordern, die zu optimierenden Ressourcen sich aber auf https://downloads.example.com befinden, erhalten Sie keine Hinweise.

Damit Hinweise für Cross-Origin-Anfragen zulässig sind, muss jeder Hinweis und jeder Ursprung mit einem Permissions-Policy-Header angegeben werden. Wenn Sie dies auf einen User-Agent-Client-Hint anwenden möchten, müssen Sie den Hint in Kleinbuchstaben schreiben und das Präfix sec- entfernen. Beispiel:

⬇️ Antwort von example.com

Accept-CH: Sec-CH-UA-Platform-Version, DPR
Permissions-Policy: ch-ua-platform-version=(self "downloads.example.com"),
                    ch-dpr=(self "cdn.provider" "img.example.com");

⬆️ Anfrage an downloads.example.com

Sec-CH-UA-Platform-Version: "10"

⬆️ Anfragen an cdn.provider oder img.example.com

DPR: 2

Wo werden User-Agent-Client-Hints verwendet?

Kurz gesagt: Sie sollten alle Instanzen umschreiben, in denen Sie entweder den User-Agent-Header parsen oder einen der JavaScript-Aufrufe verwenden, die auf dieselben Informationen zugreifen (d.h. navigator.userAgent, navigator.appVersion oder navigator.platform), um stattdessen User-Agent-Client-Hints zu verwenden.

Gehen Sie noch einen Schritt weiter und überprüfen Sie Ihre Verwendung von User-Agent-Informationen. Ersetzen Sie sie nach Möglichkeit durch andere Methoden. Oft lässt sich das gleiche Ziel mithilfe von progressiver Verbesserung, Funktionserkennung oder responsivem Design erreichen. Das Hauptproblem bei der Verwendung von User-Agent-Daten besteht darin, dass Sie immer eine Zuordnung zwischen der Property, die Sie prüfen, und dem durch sie aktivierten Verhalten vornehmen müssen. Es ist ein Wartungsaufwand, der dafür sorgt, dass die Erkennung umfassend und aktuell bleibt.

Unter Berücksichtigung dieser Vorbehalte sind im User-Agent-Client-Hint-Repository einige gültige Anwendungsfälle für Websites aufgeführt.

Was passiert mit dem User-Agent-String?

Ziel ist es, die Möglichkeiten für verdecktes Tracking im Web zu minimieren, indem die Menge der personenidentifizierbaren Informationen, die über den vorhandenen User-Agent-String offengelegt werden, reduziert wird, ohne bestehende Websites unnötig zu beeinträchtigen. Mit der Einführung von User-Agent-Client-Hints können Sie die neue Funktion jetzt testen, bevor Sie Änderungen an User-Agent-Strings vornehmen.

Mit der Zeit werden die Informationen im User-Agent-String reduziert, sodass das alte Format beibehalten wird, aber nur dieselben allgemeinen Browser- und wichtigen Versionsinformationen wie in den Standardhinweisen bereitgestellt werden. In Chromium wurde diese Änderung bis mindestens 2022 verschoben, um dem Ökosystem mehr Zeit für die Bewertung der neuen Funktionen für User-Agent-Client-Hinweise zu geben.

Sie können eine solche Version testen, indem Sie das Flag about://flags/#reduce-user-agent in Chrome 93 aktivieren. (Hinweis: Dieses Flag hieß in den Versionen Chrome 84 bis 92 about://flags/#freeze-user-agent.) Dies gibt aus Kompatibilitätsgründen einen String mit den Verlaufseinträgen zurück, aber mit entfernten Details. Sie könnten z. B. so etwas sagen:

Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Mobile Safari/537.36

Thumbnail von Sergey Zolkin auf Unsplash