Catégorie : Matériel / Traitement Audio
1. Description
L'empreinte audio utilise l'API Web Audio pour mesurer comment le matériel audio et la pile logicielle d'un appareil traitent le son. L'AudioContext, l'OscillatorNode et le DynamicsCompressorNode produisent une sortie qui varie selon :
- Implémentation du pilote audio (ALSA, PulseAudio, PipeWire, CoreAudio, WASAPI)
- Caractéristiques du DAC/ADC matériel
- Algorithmes de conversion de taux d'échantillonnage
- Comportement de la compression dynamique (courbes de threshold, knee, ratio)
- Gestion des tampons audio et latence
- Différences d'implémentation FFT
2. Vecteurs
2.1 Empreinte DynamicsCompressor
const ctx = new AudioContext()
const osc = ctx.createOscillator()
const compressor = ctx.createDynamicsCompressor()
compressor.threshold.value = -50
compressor.knee.value = 40
compressor.ratio.value = 12
osc.frequency.value = 1000
osc.type = 'sawtooth'
osc.connect(compressor)
const dest = ctx.createAnalyser()
compressor.connect(dest)
const buffer = new Float32Array(dest.fftSize)
dest.getFloatFrequencyData(buffer)
const hash = md5(buffer)
Entropie : ~8-12 bits
Stabilité : Élevée entre sessions, modérée entre mises à jour du navigateur
2.2 Latence de Base AudioContext
const ctx = new AudioContext()
const latency = ctx.baseLatency
Entropie : ~4-6 bits
Stabilité : Très Élevée — dépendante du matériel
2.3 Signaux Audio Supplémentaires
| Signal |
Description |
Entropie |
sampleRate |
Taux d'échantillonnage du contexte audio (44100, 48000, etc.) |
~1-2 bits |
maxChannelCount |
Nombre max de canaux audio supportés |
~1-2 bits |
| Mode de nombre de canaux |
'explicit' vs 'clamped-max' vs 'max' |
~1-2 bits |
| Variations de taille FFT |
Différentes implémentations FFT |
~2-3 bits |
3. Forces de l'Attaquant
| Force |
Explication |
| Verrouillé au matériel |
L'empreinte audio est déterminée par le matériel audio et les pilotes |
| Aucune autorisation requise |
AudioContext peut être créé sans consentement utilisateur |
| Rapide |
La génération d'empreinte prend ~50-100ms |
| Arrière-plan |
Ne joue pas de son audible |
| Utilisateur passif |
L'utilisateur ne peut pas savoir que ça se produit |
4. Faiblesses de l'Attaquant
| Faiblesse |
Explication |
| Blocable |
AudioContext peut être désactivé (Firefox resistFingerprinting le bloque entièrement) |
| Dépendant du navigateur |
Même matériel + différents navigateurs peuvent produire différentes sorties |
| Les mises à jour de pilotes le changent |
Les mises à jour de pilotes audio peuvent invalider les empreintes stockées |
| Le plancher de bruit change |
Le bruit de fond affecte la sortie DynamicsCompressor |
| Entropie plus faible que GPU |
~8-12 bits vs ~20+ bits pour WebGL |
5. Détection de la Manipulation
| Technique |
Comment Ça Marche |
| Détection de sortie aplatie |
Toutes les valeurs retournant -100dB n'est pas naturel |
| Comparaison de lectures croisées |
Lire le tampon audio deux fois, comparer pour les motifs de bruit injectés |
| Vérification de la latence de base |
Des valeurs de latence inhabituelles suggèrent une surcharge |
| Cohérence du taux d'échantillonnage |
Contredit d'autres signaux (taux d'échantillonnage rare + navigateur courant) |
6. Atténuations pour Obscura
6.1 Ce Qu'Obscura Peut Faire
| Atténuation |
Efficacité |
Détectabilité |
Implémentation |
| Bloquer AudioContext entièrement |
Élevée |
Moyenne |
JS : AudioContext → undefined |
| Aplatir la sortie du compresseur |
Moyenne |
Élevée |
Surcharger getFloatFrequencyData |
| Bloquer la latence de base audio |
Faible |
Moyenne |
Surcharger le getter baseLatency |
| Arrondir le taux d'échantillonnage |
Faible |
Faible |
Surcharger le getter sampleRate |
6.2 Ce Qu'Obscura Ne Peut Pas Faire
| Ne Peut Pas |
Pourquoi |
| Changer le traitement audio réel |
Le traitement audio est du matériel local |
| Usurper la sortie DynamicsCompressor |
La sortie dépend du DSP audio physique |
| Normaliser entre utilisateurs |
Différent matériel — différent traitement |
| Supprimer les canaux auxiliaires de timing |
Le timing audio est mesurable même avec l'API bloquée |
6.3 Approche Recommandée
1. Bloquer AudioContext entièrement (valeur élevée, coût faible)
2. Accepter le risque résiduel (l'audio seul est ~8-12 bits, insuffisant seul)
7. Références de Recherche
- Acar, G. et al. (2014). "The Web Never Forgets: Persistent Tracking Mechanisms in the Wild." CCS 2014.
- Englehardt, S. & Narayanan, A. (2016). "Online Tracking: A 1-million-site Measurement and Analysis." CCS 2016.
- FingerprintJS (2026). Code source :
src/sources/audio.ts.