Umgehen des erweiterten Schutzes gegen Audio-Fingerprinting in Safari 17
(fingerprint.com)- Safari 17 fügt im privaten Modus jedem Audio-API-Sample zufälliges Rauschen hinzu, um Audio-Fingerprints zu destabilisieren; FingerprintJS reagiert darauf mit einem neuen Fingerprinting-Algorithmus, der dieses Rauschen reduziert
- Die bisherige Methode nutzt die Summe von 500 Audio-Samples als Kennung; dadurch wird Safaris Rauschbereich größer als die Unterschiede zwischen Browsern, wodurch die Stabilität verloren geht
- Die neue Methode erzeugt massenhaft verrauschte Kopien desselben Audio-Samples und reduziert die Schwankung des Werts mit
(min+max)/2sowie Rundung signifikanter Stellen - Durch die Verbindung eines square
OscillatorNode, einesDynamicsCompressorNodeund einesBiquadFilterNodewurden die Unterschiede zwischen Browsern vergrößert; der minimale Unterschied beim 3396. Sample der ausgewählten Browser stieg auf0.0014% - Der neue Algorithmus ersetzt ab FingerprintJS 4.2.0 den bisherigen Audio-Fingerprint; die Berechnungszeit steigt zwar um das 1,5- bis 2-Fache, bleibt aber auch auf leistungsschwachen Geräten kurz
Wie Safari 17 Audio-Fingerprints destabilisiert
- Audio-Fingerprinting rendert ein Audiosignal mit der Audio API und OfflineAudioContext des Browsers und bildet anschließend durch Summieren der Samples eine einzelne Kennzahl als Identifikator
- Dieser Identifikator besitzt Stabilität, da er sich auch nach dem Löschen von Cookies oder dem Wechsel in den Inkognito-Modus nicht ändert; die Eindeutigkeit ist jedoch nicht hoch, weil viele Nutzer denselben Wert teilen können
- Safaris erweiterter Fingerprint-Schutz ist standardmäßig im privaten Modus aktiviert und im normalen Modus deaktiviert; er gilt sowohl für Desktop als auch für Mobilgeräte
- Die Schutzfunktion wirkt sich auch auf die Screen API und Canvas API aus, hier geht es jedoch nur um die Audio API
- Ist die Schutzfunktion aktiviert, multipliziert Safari jedes Audio-Sample mit individuellem zufälligem Rauschen
- Ein verrauschtes Sample liegt zwischen
sample*(1-magnitude)undsample*(1+magnitude) - Die Verteilung ist gleichverteilt
- Da Safari weiterhin entwickelt wird, können sich Implementierungsdetails mit der Zeit ändern
- Ein verrauschtes Sample liegt zwischen
Stellen in der Audio API, an denen Rauschen angewendet wird
- Safari wendet Rauschen an mehreren Schnittstellen an, über die Audiosignale ausgelesen werden können
- AudioWorkletNode: magnitude
0.001 - AudioBuffer::getChannelData: magnitude
0.001 - AudioBuffer::copyFromChannel: magnitude
0.001 - RealtimeAnalyser::getFloatFrequencyData: magnitude
0.25
- AudioWorkletNode: magnitude
- Da sich das Rauschen bei jeder Anwendung ändert, verändert sich der Audio-Fingerprint im privaten Modus von Safari 17 bei jeder Berechnung
- In Safari 17 auf einem M1 MacBook Air schwankt der Fingerprint zwischen
124.03516und124.04545; die Differenz beträgt etwa0.008% - Der kleinste bestehende Unterschied zwischen Audio-Fingerprints verschiedener Browser beträgt
0.0000023%und ist damit deutlich kleiner als Safaris Rauschbereich - Um das Rauschen zu beseitigen, müsste auf etwa eine Nachkommastelle gerundet werden; bleiben jedoch weniger als 6 Stellen übrig, lassen sich einige Browser schwer unterscheiden, wodurch die Eindeutigkeit sinkt
Die drei Schritte des neuen Algorithmus
- Der neue Audio-Fingerprinting-Algorithmus von FingerprintJS durchläuft drei Schritte, um das von Safari hinzugefügte Rauschen zu reduzieren
- Reduktion der Varianz des Rauschens
- Vergrößerung der Abstände zwischen den Browser-Identifikationszahlen
- Entfernung des verbleibenden Rauschens durch Rundung
- Der bisherige Audio-Fingerprint ist die Summe von 500 Audio-Samples; wird jedem Sample gleichverteiltes Rauschen hinzugefügt, nähert sich das Gesamtrauschen des Fingerprints einer Normalverteilung an
- Der Mittelwert einer Normalverteilung muss aus dem Mittel vieler Samples geschätzt werden; der Mittelwert einer Gleichverteilung lässt sich dagegen mit
(min+max)/2aus weniger Samples präzise schätzen - Im Experimentcode benötigte die Normalverteilung bei gleicher Präzisionsanforderung
524,288Samples, während bei der Gleichverteilung4,096Samples ausreichten - Die neue Methode wechselt vom Summen-Fingerprint zur Erfassung nur eines einzelnen Audio-Samples, um gleichverteiltes Rauschen zu behandeln
- Wegen dieser Änderung ist der neue Fingerprint nicht mit dem bisherigen kompatibel; für eine Umstellung ohne Verlust von Besucher-Identifikatoren ist ein eigener Ansatz nötig
Verrauschte Kopien desselben Audio-Samples erzeugen
- Mehrfaches Aufrufen von
getChannelDataauf einerAudioBuffer-Instanz funktioniert nicht- Das Rauschen wird einmal pro
AudioBuffer-Instanz angewendet getChannelDataderselben Instanz gibt dasselbe Signal zurück
- Das Rauschen wird einmal pro
- Führt man den gesamten Prozess zur Erzeugung des Audiosignals mehrfach aus, lassen sich viele
AudioBuffer-Instanzen erzeugen; für die Fingerprint-Berechnung ist das jedoch zu langsam- Für 6.000 verrauschte Samples lag die schnellste Zeit auf einem M1 MacBook bei 7 Sekunden
- Bei 60.000 schaffte Safari es nicht, die Aufgabe abzuschließen
- Ein besserer Ansatz ist, eine
AudioBuffer-Instanz zu erzeugen, die dasselbe Audiosignal wiederholt- Das erste Audiosignal wird gerendert,
getChannelDatawird jedoch nicht aufgerufen - Ein zweiter, längerer OfflineAudioContext wird erstellt, und das ursprüngliche Signal wird als AudioBufferSourceNode verwendet
- Mit
loop,loopStartundloopEndwird ein Teil des ursprünglichen Signals wiederholt - Nach der Wiederholung fügt Safari Rauschen hinzu, wodurch Kopien desselben Audio-Samples mit jeweils unterschiedlichem Rauschen entstehen
- Das erste Audiosignal wird gerendert,
- Mit dieser Methode lassen sich die benötigte Anzahl an verrauschten Kopien mit nur zwei Audio-Renderings erzeugen
- Das Rauschen verschwindet nicht vollständig, aber die Varianz wird kleiner als beim ursprünglichen Audio-Sample
8,192Kopien: Bereich über 100 Ausführungen0.000387%, auf einem M1 MacBook2.6ms65,536Kopien:0.0000123%,4.1ms262,144Kopien:0%,7.5ms
Unterschiede zwischen Browsern bei Audio-Samples vergrößern
- Reduziert man die Zahl der Kopien, verbessert sich die Performance, aber die Varianz der Ergebnisse steigt; daher wird das Basissignal geändert, um die Unterschiede zwischen Browsern bei Audio-Samples zu vergrößern
- Nach Experimenten mit mehreren integrierten Audio-Nodes ergab sich folgende Signalerzeugungskette, bei der die Sample-Unterschiede zwischen Browsern größer werden
- square OscillatorNode
- DynamicsCompressorNode
- BiquadFilterNode vom Typ
allpass
- Das 3396. Sample des Audiosignals zeigte die größten Unterschiede zwischen Browsern; dieser Wert wurde durch den Vergleich aller Samples mehrerer Browser gefunden
- In der ausgewählten Browser-Stichprobe betrug der kleinste Unterschied dieses neuen Samples
0.0014%- Das ist größer als der kleinste Unterschied des bisherigen Fingerprints von
0.0000023% - Dadurch können gröbere Rauschunterdrückung und Rundung angewendet werden
- Das ist größer als der kleinste Unterschied des bisherigen Fingerprints von
Stabilisierung des Fingerprints durch Rundung
- Auch wenn der Rauschbereich eines einzelnen Samples kleiner wird, schwankt der Wert weiterhin; für die Verwendung als finaler Fingerprint ist daher Rundung nötig
- Da Rauschen nicht als absoluter Wert, sondern relativ zum Audio-Sample-Wert angewendet wird, erfolgt die Rundung nicht nach Nachkommastellen, sondern nach signifikanten Stellen
- Für die Unterscheidung der ausgewählten Browser reichten 5 signifikante Stellen aus; da jedoch nicht alle Browser und künftigen Änderungen überprüft werden können, werden mehr Stellen verwendet
- Im privaten Modus von Safari 17 ist je nach Rundungspräzision folgende Anzahl an Kopien für Stabilisierung nötig
- 6 signifikante Stellen:
15,000Kopien, bei warmem Safari 17 auf einem M1 MacBook3ms - 7 signifikante Stellen, wobei die letzte Stelle auf ein Vielfaches von 5 gerundet wird:
30,000Kopien,4ms - 7 signifikante Stellen, wobei die letzte Stelle auf die nächstgelegene gerade Zahl gerundet wird:
70,000Kopien,6ms - 7 oder mehr signifikante Stellen:
400,000Kopien,12ms
- 6 signifikante Stellen:
- Die finale Wahl sind 7 signifikante Stellen, wobei die letzte Stelle
0oder5wird; zur Erhöhung der Stabilität wurde die Zahl der Kopien auf40,000erhöht - Die so gerundete Zahl wird zu einem neuen Audio-Fingerprint, der sich auch bei aktiviertem erweiterten Fingerprint-Schutz in Safari 17 nicht ändert
- Der neue Fingerprint wird so bewertet, dass er dieselbe Eindeutigkeit wie der bisherige Audio-Fingerprint besitzt
Performance und Ausführungsbeschränkungen
- Bei einem warmen Browser auf einer leeren Seite ist der neue Algorithmus insgesamt langsamer als der bisherige
- MacBook Air 2020 Safari 17.3: bisher
2ms, neue Methode4ms - MacBook Air 2020 Chrome 120: bisher
5ms, neue Methode8ms - iPhone 13 mini Safari 17.3: bisher
8ms, neue Methode12ms - Galaxy J7 Prime Chrome 120: bisher
33ms, neue Methode45ms - BrowserStack Windows 11 Firefox 121: bisher
10ms, neue Methode18ms
- MacBook Air 2020 Safari 17.3: bisher
- Die Performance des neuen Algorithmus ist gegenüber dem bisherigen 1,5- bis 2-mal schlechter, die Berechnungszeit bleibt jedoch auch auf leistungsschwachen Geräten kurz
- Da der Browser manche Aufgaben an den
OfflineAudioRender-Thread delegiert, bleibt die Seite während des größten Teils der Audio-Fingerprint-Berechnung reaktionsfähig - Die Web Audio API kann nicht in Web Workers verwendet werden, daher lässt sich der Audio-Fingerprint nicht in einem Worker berechnen
- Zur Performance-Verbesserung kann per User-Agent-String geprüft werden, ob Safari 17 oder neuer verwendet wird; der neue Algorithmus kann nur dort eingesetzt werden, während andere Browser beim bisherigen Algorithmus bleiben
Unterschiede zu Tor und Brave
- Tor deaktiviert die Web Audio API vollständig, daher ist Audio-Fingerprinting unmöglich
- Brave fügt Audiosignalen wie Safari 17 Rauschen hinzu, verwendet jedoch eine andere Methode
- Safari multipliziert jedes Audio-Sample mit einem eigenen Zufallswert
- Brave erzeugt einmal einen zufälligen Multiplikator namens
fudge factorund multipliziert alle Audio-Samples mit demselben Wert- Dieser Wert bleibt innerhalb der Seite erhalten
- Er ändert sich nur in einer neuen normalen Sitzung oder Inkognito-Sitzung
- In Brave wird auf alle Kopien dasselbe Rauschen angewendet, egal wie viele Kopien eines Audio-Samples erzeugt werden; daher funktioniert der mathematische Ansatz zur Rauschbeseitigung für Safari dort nicht
- Der frühere Ansatz zur Entfernung von Brave-Rauschen funktioniert jedoch weiterhin, und die neue Methode zur Signalerzeugung, die die Fingerprint-Unterschiede zwischen Browsern vergrößert, kann die Fehlertoleranz erhöhen
Anwendung in FingerprintJS
- Der neue Audio-Fingerprinting-Algorithmus hat in FingerprintJS die bisherige Methode ersetzt und wurde erstmals in 4.2.0 veröffentlicht
- Der vollständige Implementierungscode befindet sich im GitHub-Repository von FingerprintJS
- Der Audio-Fingerprint ist eines von mehreren Signalen, die die Open-Source-Bibliothek zur Erstellung eines Browser-Fingerprints nutzt
- FingerprintJS schließt nicht pauschal alle im Browser verfügbaren Signale ein, sondern analysiert Stabilität und Eindeutigkeit jedes Signals separat und bewertet dessen Einfluss auf die Fingerprint-Genauigkeit
- Der Audio-Fingerprint trägt nur wenig zur Eindeutigkeit bei, gilt aber wegen seiner hohen Stabilität als Signal, das die Genauigkeit des gesamten Fingerprints leicht erhöht
1 Kommentare
Meinungen auf Hacker News
Eine weitere interessante Technik zur Identifizierung von Nutzern im Web ist GPU-Fingerprinting; sie wurde 2022 unter dem Codenamen „DrawnApart“ vorgestellt.
Dabei werden per WebGL die Anzahl und Geschwindigkeit der GPU-Ausführungseinheiten gezählt sowie die Abschlusszeiten beim Vertex-Rendering und die Verarbeitung von Stall-Funktionen gemessen.
Heutzutage, besonders wenn man das Interesse an Seitenkanalangriffen betrachtet, funktioniert ein Ansatz, bei dem man gleichverteiltes Rauschen zu Werten hinzufügt, aus denen Daten lecken, so gut wie sicher nicht.
Denn wenn man mehr Samples sammelt, kann man das Rauschen herausrechnen. Ich weiß nicht, warum Safari das eingebaut hat. Es kann Fingerprinting zwar lästiger machen, aber wie dieser Artikel zeigt, scheint es letztlich in irgendeiner Form weitgehend umgehbar zu sein.
Es fühlt sich wie Privacy-Theater an, bei dem wichtiger geworden ist, ob man der Öffentlichkeit eine plausibel klingende Geschichte erzählen kann, als ob es technisch wirksam ist.
Kann jemand erklären, warum die Ergebnisse überhaupt unterschiedlich sind? Ich frage mich zum Beispiel, warum Audio-Fingerprinting möglich ist.
Wenn man mit der Web Audio API ein kleines Signal erzeugt, liefern alle Browser fast dasselbe Ergebnis, aber die winzigen Unterschiede lassen sich nutzen, um sie voneinander zu unterscheiden.
Es ist bedauerlich, dass Browserentwickler dem Audio-Buffer-Processing Rauschen hinzufügen müssen, um das zu verhindern.
Kurz gesagt können selbst innerhalb derselben Codebasis unterschiedliche Codepfade, etwa SIMD-Varianten, leicht unterschiedliche Gleitkomma-Ergebnisse erzeugen. Das scheint damit zusammenzuhängen, dass Gleitkommaoperationen empfindlicher auf Dinge wie die Reihenfolge der Operationen reagieren, als man erwarten würde.
Selbst wenn derselbe Algorithmus und dieselbe Formel korrekt implementiert werden, können die Ergebnisse leicht voneinander abweichen.
Korrigiert mich, wenn ich falsch liege. Der Grund, warum die Fingerprinting-Umgehung hier erfolgreich ist, scheint auf die Entscheidung in der Web-Audio-API-Spezifikation zurückzugehen, die Behandlung des Antialiasings von OscillatorNode so offen zu lassen:
„Es gibt viele praktische Ansätze, die eine Implementierung wählen kann, um dieses Aliasing zu vermeiden. Unabhängig vom Ansatz ist das ideale zeitdiskrete digitale Audiosignal mathematisch klar definiert. Die Kompromisse bei der Implementierung liegen in den Implementierungskosten in Form von CPU-Nutzung und darin, wie treu dieses Ideal erreicht wird. Es wird erwartet, dass Implementierungen ein gewisses Maß an Sorgfalt aufwenden, um dieses Ideal zu erreichen; auf leistungsschwacher Hardware ist es jedoch vernünftig, Ansätze mit geringerer Qualität und geringeren Kosten in Betracht zu ziehen.“
Meiner Ansicht nach bedeutet das, dass die hier ausgenutzte Ausgabe von OscillatorNode zwischen Browsern und sogar im selben Browser auf unterschiedlicher Hardware mit ziemlicher Sicherheit nicht deterministisch ist. Die Nichtdeterministik basiert auf der vom Browser gewählten Antialiasing-Methode oder auf mehreren Pfaden, die derselbe Browser je nach Hardware auswählt. Dazu gehören auch Änderungen oder Anpassungen desselben Antialiasing-Algorithmus.
Warum man das Antialiasing den Browsern überlassen hat, ist mir nicht ganz klar. Hochwertige Audio-Apps oder -Bibliotheken werden die Art, wie Aliasing in den von ihnen erzeugten Signalen vermieden wird, vollständig kontrollieren wollen und nicht den Standardoszillator verwenden. Umgekehrt ist es einer Web-App, die einen beliebigen Antialiasing-Algorithmus und die daraus folgenden browserspezifischen Unterschiede akzeptiert, wahrscheinlich ziemlich egal, ob der Algorithmus eine hartcodierte SIMD-Anweisung oder ein 20 MB großes JavaScript-Web-Audio-Helferframework ist.
1: https://webaudio.github.io/web-audio-api/#OscillatorNode
Ich frage mich auch, ob man hier eine ähnliche Lösung anwenden könnte wie Hixie bei der Standardisierung des HTML5-Parsers: Ein Fachexperte spezifiziert einen exakten, deterministischen Antialiasing-Algorithmus, der gut genug funktioniert, und danach verwenden alle Browser diesen. Ein messbarer Performance-Verlust wäre vermutlich nur in Web-Audio-API-Tutorials zu sehen, die Signale mit dem standardmäßigen antialiasenden Oszillator erzeugen.
Deshalb möchte man Implementierungen je nach verfügbarer Rechenleistung, Akku usw. entscheiden lassen, wie viel sie dafür aufwenden.
Es war töricht, eine Node-Graph-Audio-API in den Browser einzubauen. Es hätte einfach nur AudioWorklet geben sollen.
https://web.archive.org/web/20120505042746/https://developer...
Widerlich
Ich verstehe schon grundsätzlich nicht, warum die Audio-API ohne Zustimmung der Website genutzt werden kann. Das ließe sich scheinbar leicht mit einem einfachen Dialog wie „Diese Website möchte Ihr Audiogerät verwenden“ beheben.
Das Internet in seiner jetzigen Form hat den Traum vom Personal Computing ziemlich ruiniert. Unternehmen und Staaten sind gegenüber Einzelpersonen viel zu asymmetrisch mächtig. Sollte meine Technik ohne ausdrückliche Zustimmung Daten an Server senden können?
Andererseits: Als ich den Browser-Cache gelöscht und ein VPN eingeschaltet habe, haben sie mich immerhin fälschlich als neuen Besucher erkannt. Trotzdem ist das Geschäftsmodell niederträchtig.
Selbst wenn das eine wohlwollende Interpretation ist: Es hat großen Wert, solche Forschung zu veröffentlichen und ans Licht zu bringen. Statt zu befürchten, dass alle mehr stehlen, nur weil jemand schreibt, dass ein bestimmter grüner Rucksack einer bestimmten Marke beim Diebstahl hilft, würde ich eher darauf setzen, dass Läden diese Methode danach besser erkennen.
Statt zu jedem Sample einen Zufallswert hinzuzufügen, könnte Safari offenbar auch deterministisches Rauschen hinzufügen, das auf einem Schlüssel basiert, der sich jede Stunde ändert.
Wenn man es als Funktion aus Audio-Sample und Schlüssel gestaltet, ist das Rauschen innerhalb derselben Sitzung gleich, aber eine Stunde später fürs Tracking nutzlos.
Um das zu beheben, muss man den Informationsabfluss selbst beseitigen; ihn nur mit einer Schicht zufälliger Abweichung zu überdecken, reicht nicht.
Zum Beispiel etwa so:
RNG_SEED = HMAC_SHA256(PERSISTENT_SECRET,Location.origin).Ich bin jetzt wirklich bereit, „diese Person“ zu werden, die JavaScript abschaltet und so im Web surft.
Wenn sie anderswo nur ein paar weitere Bits zusammenkratzen, kann man dich eindeutig identifizieren. Nach meinem Maßstab können diese Leute trotzdem zusammen mit dem Rest der Adtech-Branche auf die Golgafrinchan Ark B verfrachtet werden.
Eine Website, die ich neulich besucht habe, verwendete zwar Markup, aber statt es zu HTML zu kompilieren und statisch auszuliefern, wurde es clientseitig per JavaScript gerendert. WTF.
Nicht nur wegen DDoS-Prüfungen wie bei Cloudflare; inzwischen wird sogar das, was eigentlich im HTML der Seite stehen sollte, per JavaScript geladen.
Je feindseliger das Internet wird, desto richtiger wird diese Entscheidung.
Ich verstehe nicht ganz, wie diese Methode mehr als ein paar Tausend eindeutige Kombinationen erzeugen kann.
Browsertyp × Browserversion × Betriebssystemversion × Beschleuniger-Version × … was noch? Es scheint nicht genug Variation zu geben, um aus der Ferne eindeutig zu sein.
Nimmt diese Technik Fingerprints anhand von Unterschieden bei Hardware, Treibern und Betriebssystem in der Audioverarbeitung, oder betrachtet sie nur die Browser-Software?
Ich nehme an, es gab oder gibt noch ähnliche Techniken, die Unterschiede der darunterliegenden Grafikgeräte offenlegen.
Eines der Beispiele im Artikel ist die schnelle Fourier-Transformation (FFT). Jedes Betriebssystem hat eine Version dieser Funktion, aber sie wird im Laufe der Zeit tendenziell optimiert und verhält sich je nach verfügbaren SIMD-Befehlen oft von CPU zu CPU unterschiedlich.