Saltar al contenido principal
it/blog/obscura/research/audio-fingerprinting/

obscura/research/audio-fingerprinting

2 min di lettura

Panoramica

Il fingerprinting audio utilizza l'API Web Audio (AudioContext) per generare un identificatore unico basato su come l'hardware audio e il software del dispositivo elaborano un segnale generato.

Meccanismo

  1. Crea un AudioContext
  2. Genera un segnale oscillatore (onda sinusoidale a una frequenza specifica)
  3. Elabora attraverso DynamicsCompressorNode
  4. Estrai il segnale elaborato tramite getChannelData()
  5. Applica un hash all'array risultante di numeri in virgola mobile
const ctx = new AudioContext()
const osc = ctx.createOscillator()
const compressor = ctx.createDynamicsCompressor()
osc.connect(compressor)
compressor.connect(ctx.destination)

// Impostazioni compressore
compressor.threshold.value = -50
compressor.knee.value = 40
compressor.ratio.value = 12
compressor.reduction.value = -20
osc.frequency.value = 1000
osc.type = 'sawtooth'

// Elabora ed estrai
const analyser = ctx.createAnalyser()
const buffer = new Float32Array(analyser.fftSize)
analyser.getFloatFrequencyData(buffer)
const hash = md5(buffer) // unico per stack audio

Fonti di Entropia

Fonte Variabilità
Driver audio e hardware Alta
Supporto frequenza di campionamento Media
Implementazione elaborazione dinamica Media
Stack audio SO (PulseAudio, ALSA, CoreAudio, WASAPI) Alta
Conteggio canali audio Bassa

Mitigazione

Al proxy

L'AudioContext viene eseguito interamente nel browser: il proxy non può modificare il suo output.

Tramite JS iniettato

Sovrascrivi AudioContext.prototype.getChannelData o AnalyserNode.prototype.getFloatFrequencyData per restituire dati generici/appiattiti.

// Override iniettato
const originalGetFloatFrequencyData = AnalyserNode.prototype.getFloatFrequencyData
AnalyserNode.prototype.getFloatFrequencyData = function(array) {
  originalGetFloatFrequencyData.call(this, array)
  // Appiattisci/rumorizza l'output
  for (let i = 0; i < array.length; i++) {
    array[i] = -100 // segnale piatto
  }
}

Problema: Il sito può rilevare la manomissione verificando se l'output è troppo uniforme rispetto all'output hardware reale.

Conclusioni

  • Il fingerprinting audio è specifico di CPU/SO/hardware
  • Non può essere falsificato a livello di proxy
  • L'iniezione JS può attenuarlo ma non completamente
  • Approccio migliore: override + rumore coerente tramite JS iniettato