Cómo eludir la protección avanzada de Safari 17 contra huellas de audio
(fingerprint.com)- Safari 17 agrega ruido aleatorio a cada muestra de la Audio API en modo privado para alterar la huella de audio, pero FingerprintJS respondió con un nuevo algoritmo de huella que lo reduce
- El método anterior usaba la suma de 500 muestras de audio como identificador, por lo que el rango de ruido de Safari se volvió mayor que las diferencias entre navegadores y perdió estabilidad
- El nuevo método crea una gran cantidad de copias con ruido de la misma muestra de audio y reduce la variación del valor con
(min+max)/2y redondeo de cifras significativas - Se conectaron un
OscillatorNodesquare, unDynamicsCompressorNodey unBiquadFilterNodepara aumentar las diferencias entre navegadores, y la diferencia mínima de la muestra 3396 entre los navegadores seleccionados se elevó hasta0.0014% - El nuevo algoritmo reemplazó la huella de audio anterior desde FingerprintJS 4.2.0; el tiempo de cálculo aumenta entre 1.5 y 2 veces, pero incluso en dispositivos de gama baja termina en poco tiempo
Cómo Safari 17 altera la huella de audio
- La huella de audio consiste en renderizar una señal de audio con la Audio API y OfflineAudioContext del navegador, y luego sumar las muestras para obtener un único número identificador
- Este identificador tiene estabilidad, ya que no cambia al borrar cookies ni al cambiar a modo incógnito, pero su unicidad no es alta porque muchos usuarios pueden compartir el mismo valor
- La protección avanzada contra huellas de Safari 17 está activada por defecto en modo privado y desactivada en modo normal, y se aplica tanto en escritorio como en móvil
- La protección también afecta a las API Screen y Canvas, pero aquí solo se trata la Audio API
- Cuando la protección está activada, Safari multiplica cada muestra de audio por un ruido aleatorio individual
- La muestra con ruido queda entre
sample*(1-magnitude)ysample*(1+magnitude) - La distribución es uniforme
- Como el desarrollo de Safari sigue en curso, los detalles de implementación pueden cambiar con el tiempo
- La muestra con ruido queda entre
Puntos de la Audio API donde se aplica el ruido
- Safari aplica ruido en varias interfaces desde las que se puede leer la señal de audio
- AudioWorkletNode: magnitud
0.001 - AudioBuffer::getChannelData: magnitud
0.001 - AudioBuffer::copyFromChannel: magnitud
0.001 - RealtimeAnalyser::getFloatFrequencyData: magnitud
0.25
- AudioWorkletNode: magnitud
- Como el ruido cambia cada vez que se aplica, en el modo privado de Safari 17 la huella de audio cambia cada vez que se calcula
- En Safari 17 sobre una MacBook Air M1, la huella fluctúa entre
124.03516y124.04545, con una diferencia de aproximadamente0.008% - La menor diferencia entre huellas de audio tradicionales según el navegador es
0.0000023%, mucho menor que el rango de ruido de Safari - Para eliminar el ruido habría que redondear aproximadamente a un decimal, pero si se dejan menos de 6 dígitos se vuelve difícil distinguir algunos navegadores y baja la unicidad
Tres etapas del nuevo algoritmo
- El nuevo algoritmo de huella de audio de FingerprintJS pasa por tres etapas para reducir el ruido agregado por Safari
- Reducir la dispersión del ruido
- Aumentar la distancia entre los números identificadores de los navegadores
- Eliminar el ruido restante mediante redondeo
- Como la huella de audio anterior es la suma de 500 muestras de audio, cuando a cada muestra se le agrega ruido con distribución uniforme, el ruido total de la huella se aproxima a una distribución normal
- La media de una distribución normal debe estimarse promediando muchas muestras, pero la media de una distribución uniforme puede estimarse con mayor precisión usando
(min+max)/2con menos muestras - En el código experimental, para la misma condición de precisión la distribución normal necesitó
524,288muestras, mientras que para la distribución uniforme bastaron4,096 - El nuevo método deja de usar una huella por suma y pasa a recolectar solo una muestra de audio para tratar el ruido de distribución uniforme
- Debido a este cambio, la nueva huella no es compatible con la anterior; para migrar sin perder identificadores de visitantes se requiere un enfoque aparte
Crear copias con ruido de la misma muestra de audio
- Llamar varias veces a
getChannelDatasobre una instancia deAudioBufferno funciona- El ruido se aplica una sola vez por cada instancia de
AudioBuffer getChannelDatasobre la misma instancia devuelve la misma señal
- El ruido se aplica una sola vez por cada instancia de
- Ejecutar muchas veces todo el proceso de generación de la señal de audio permitiría crear muchas instancias de
AudioBuffer, pero es demasiado lento para calcular huellas- Para 6,000 muestras con ruido, el tiempo más rápido en una MacBook M1 fue de 7 segundos
- Con 60,000, Safari no logró completar la tarea
- Un método mejor es crear una instancia de
AudioBufferque repita la misma señal de audio- Se renderiza la primera señal de audio, pero no se llama a
getChannelData - Se crea un segundo OfflineAudioContext más largo y se usa la señal original como AudioBufferSourceNode
- Se repite una parte de la señal original con
loop,loopStartyloopEnd - Después de la repetición, Safari agrega el ruido, por lo que se obtienen copias de la misma muestra de audio con ruidos distintos
- Se renderiza la primera señal de audio, pero no se llama a
- Este método permite crear la cantidad necesaria de copias con ruido con solo 2 renderizados de audio
- El ruido no desaparece por completo, pero su dispersión es menor que la de la muestra de audio original
8,192copias: rango de0.000387%en 100 ejecuciones,2.6msen una MacBook M165,536copias:0.0000123%,4.1ms262,144copias:0%,7.5ms
Aumentar las diferencias de muestras de audio entre navegadores
- Reducir el número de copias mejora el rendimiento, pero aumenta la dispersión del resultado, por lo que se cambió la señal base para aumentar las diferencias de las muestras de audio entre navegadores
- Tras experimentar con varios nodos de audio integrados, la cadena de generación de señal que aumenta las diferencias de muestras entre navegadores es la siguiente
- OscillatorNode square
- DynamicsCompressorNode
- BiquadFilterNode de tipo
allpass
- La muestra 3396 de la señal de audio fue la que mostró la mayor diferencia entre navegadores, un valor encontrado al comparar todas las muestras de varios navegadores
- En la muestra de navegadores seleccionada, la menor diferencia de esta nueva muestra fue
0.0014%- Es mayor que la menor diferencia de la huella anterior,
0.0000023% - Gracias a eso se puede aplicar una eliminación de ruido más gruesa y redondeo
- Es mayor que la menor diferencia de la huella anterior,
Estabilizar la huella mediante redondeo
- Aunque el rango de ruido de una sola muestra se reduzca, el valor sigue variando, por lo que se necesita redondeo para usarlo como huella final
- Como el ruido se aplica de forma relativa al valor de la muestra de audio y no como valor absoluto, el redondeo se hace por cifras significativas, no por posiciones decimales
- Para distinguir los navegadores seleccionados bastaban 5 cifras significativas, pero como no se pueden verificar todos los navegadores ni los cambios futuros, se usan más dígitos
- En el modo privado de Safari 17, la cantidad de copias necesarias para estabilizar según la precisión del redondeo es la siguiente
- 6 cifras significativas:
15,000copias,3mscon Safari 17 en una MacBook M1 en estado warm - 7 cifras significativas, redondeando el último dígito a múltiplos de 5:
30,000copias,4ms - 7 cifras significativas, redondeando el último dígito al par más cercano:
70,000copias,6ms - 7 cifras significativas o más:
400,000copias,12ms
- 6 cifras significativas:
- La elección final es usar 7 cifras significativas y hacer que el último dígito sea
0o5; para aumentar la estabilidad, el número de copias se elevó a40,000 - Este número redondeado se convierte en una nueva huella de audio que no cambia aunque la protección avanzada contra huellas de Safari 17 esté activada
- Se evalúa que la nueva huella tiene la misma unicidad que la huella de audio anterior
Rendimiento y restricciones de ejecución
- En un navegador warm con una página vacía, el nuevo algoritmo suele ser más lento que el anterior
- MacBook Air 2020 Safari 17.3: anterior
2ms, nuevo método4ms - MacBook Air 2020 Chrome 120: anterior
5ms, nuevo método8ms - iPhone 13 mini Safari 17.3: anterior
8ms, nuevo método12ms - Galaxy J7 Prime Chrome 120: anterior
33ms, nuevo método45ms - BrowserStack Windows 11 Firefox 121: anterior
10ms, nuevo método18ms
- MacBook Air 2020 Safari 17.3: anterior
- El rendimiento del nuevo algoritmo empeora entre 1.5 y 2 veces respecto del anterior, pero el tiempo de cálculo sigue siendo corto incluso en dispositivos de gama baja
- Como el navegador delega parte del trabajo al hilo
OfflineAudioRender, la página mantiene su capacidad de respuesta durante la mayor parte del cálculo de la huella de audio - La Web Audio API no puede usarse en web workers, por lo que no se puede calcular la huella de audio en un worker
- Para mejorar el rendimiento, se puede verificar con la cadena de user agent si se trata de Safari 17 o superior, usar el nuevo algoritmo solo en Safari 17 o superior y mantener el algoritmo anterior en otros navegadores
Diferencias con Tor y Brave
- Tor desactiva por completo la Web Audio API, por lo que no es posible la huella de audio
- Brave agrega ruido a la señal de audio como Safari 17, pero lo hace de otra manera
- Safari multiplica cada muestra de audio por un valor aleatorio separado
- Brave crea una vez un multiplicador aleatorio llamado
fudge factory multiplica todas las muestras de audio por el mismo valor- Este valor se mantiene dentro de la página
- Solo cambia en una nueva sesión normal o sesión incógnita
- En Brave, por más copias de muestras de audio que se creen, el mismo ruido se aplica a todas, por lo que el método matemático de eliminación de ruido para Safari no funciona
- Sin embargo, el método anterior de eliminación de ruido de Brave sigue funcionando, y el nuevo método de generación de señal que aumenta la diferencia de huellas entre navegadores puede ampliar el margen de tolerancia al error
Aplicación en FingerprintJS
- El nuevo algoritmo de huella de audio reemplazó al método anterior en FingerprintJS y se publicó por primera vez en la versión 4.2.0
- El código completo de la implementación está en el repositorio de GitHub de FingerprintJS
- La huella de audio es una de las varias señales que usa la biblioteca open source para crear huellas de navegador
- FingerprintJS no incluye sin más todas las señales que puede obtener del navegador, sino que analiza por separado la estabilidad y unicidad de cada señal para determinar su impacto en la precisión de la huella
- Se considera que la huella de audio contribuye poco a la unicidad, pero que por su alta estabilidad es una señal que mejora ligeramente la precisión general de la huella
1 comentarios
Comentarios de Hacker News
Otra técnica interesante para identificar usuarios en línea es la toma de huellas de GPU, presentada en 2022 con el nombre en clave "DrawnApart".
Consiste en contar la cantidad y la velocidad de las unidades de ejecución de la GPU con WebGL, y medir el tiempo de finalización del renderizado de vértices, el procesamiento de funciones de stall, etc.
Hoy en día, especialmente viendo el interés en los ataques de canal lateral, parece casi obvio que el método de sumar ruido uniforme a los valores por los que se filtran datos no funciona.
Porque si se recopilan más muestras, se puede eliminar el ruido. No sé por qué Safari incorporó esto. Puede hacer que la toma de huellas sea más molesta, pero como en este artículo, al final parece que en gran medida se puede superar de alguna forma.
Se siente como teatro de privacidad, donde importa más poder contarle al público una historia convincente que si técnicamente es efectivo.
Para empezar, ¿alguien puede explicar por qué los resultados son diferentes? Por ejemplo, me intriga por qué es posible la toma de huellas de audio.
Si se genera una señal pequeña con Web Audio API, todos los navegadores producen casi el mismo resultado, pero se pueden usar diferencias muy pequeñas para distinguirlos.
Es una lástima que los desarrolladores de navegadores tengan que añadir ruido al procesamiento de búferes de audio para evitarlo.
En resumen, incluso dentro de la misma base de código, distintas rutas de código, por ejemplo variantes SIMD, pueden producir resultados de punto flotante sutilmente distintos. Parece estar relacionado con que las operaciones de punto flotante son más sensibles de lo esperado a cosas como el orden de las operaciones.
Incluso implementando correctamente el mismo algoritmo y la misma fórmula, los resultados pueden variar un poco.
Corríjanme si me equivoco. La razón por la que aquí funciona eludir la toma de huellas parece reducirse a la decisión de dejar así de abierto en la especificación de Web Audio API el manejo del antialiasing de OscillatorNode.
"Hay varios enfoques prácticos que una implementación puede adoptar para evitar este aliasing. Independientemente del enfoque, la señal de audio digital ideal en tiempo discreto está matemáticamente bien definida. Las concesiones de implementación están entre el costo de implementación en términos de uso de CPU y qué tan fielmente se alcanza ese ideal. Aunque se espera que las implementaciones pongan cierto cuidado en alcanzar ese ideal, en hardware de gama baja es razonable considerar enfoques de menor calidad y menor costo."
A mi entender, esto significa que la salida de OscillatorNode que se explota aquí casi con seguridad no es determinista entre navegadores, e incluso dentro del mismo navegador en hardware distinto. La no determinación se basa en el método de antialiasing elegido por el navegador, o en varias rutas seleccionadas dentro del mismo navegador según el hardware. Eso incluye también cambios o modificaciones al mismo algoritmo de antialiasing.
No estoy muy seguro de por qué dejaron el antialiasing en manos del navegador. Las apps o librerías de audio de alta calidad querrán controlar por completo cómo evitan el aliasing de las señales que generan, y no usarán el oscilador básico. En cambio, una app web que acepte un algoritmo de antialiasing arbitrario y las diferencias entre navegadores resultantes probablemente no se preocupe demasiado por si el algoritmo son instrucciones SIMD hardcodeadas o un framework auxiliar de JavaScript para Web Audio de 20 MB.
1: https://webaudio.github.io/web-audio-api/#OscillatorNode
Me pregunto si aquí podría aplicarse la misma solución que usó Hixie al estandarizar el parser de HTML5. Es decir, que un experto del área especifique un algoritmo de antialiasing exacto y determinista que funcione suficientemente bien, y que luego todos los navegadores lo usen. La pérdida de rendimiento medible probablemente solo se vería en tutoriales de Web Audio API que generan señales con el oscilador básico con antialiasing.
Por eso se quiere permitir que la implementación decida cuánto gastar según los recursos de cómputo disponibles, la batería, etc.
Fue una tontería meter una API de audio de grafo de nodos en el navegador. Solo debería haber existido AudioWorklet.
https://web.archive.org/web/20120505042746/https://developer...
Repugnante
Para empezar, no entiendo por qué la API de audio puede usarse sin permiso del sitio web. Parece algo fácil de arreglar con un cuadro de diálogo simple como "Este sitio quiere usar el dispositivo de sonido".
Internet, en su forma actual, arruinó buena parte del sueño de la computación personal. Porque las empresas y los Estados son demasiado fuertes de manera asimétrica frente a las personas. ¿Debería ser posible que mi tecnología envíe datos a un servidor sin aprobación explícita?
Por otro lado, al borrar la caché del navegador y activar una VPN, sí me identificó erróneamente como un visitante nuevo. Aun así, el modelo de negocio es vil.
Incluso con una interpretación optimista, hay mucho valor en publicar este tipo de investigación y sacarla a la luz. Más que preocuparme por si todos van a robar más porque salió un artículo diciendo que una mochila verde de cierta marca ayuda a cometer robos, me inclino a pensar que las tiendas tendrán más posibilidades de detectar mejor ese método.
En vez de sumar un valor aleatorio a cada muestra, parece que Safari podría sumar ruido determinista basado en una clave que cambie cada hora.
Si se construye como una función de la muestra de audio y la clave, el ruido sería el mismo dentro de la misma sesión, pero inútil para rastrear una hora después.
Para arreglar esto hay que eliminar la propia fuga de información; no basta con taparla con una capa de desviación aleatoria.
Por ejemplo, algo como
RNG_SEED = HMAC_SHA256(PERSISTENT_SECRET,Location.origin).Ya estoy realmente listo para convertirme en "esa persona" que navega la web con JavaScript desactivado.
Si raspan unos pocos bits más de otros lados, podrían identificarte de forma única. Aun así, según mi criterio, a esta gente la podrían mandar junto con el resto de la industria adtech en el Ark B de Golgafrinchan.
Un sitio web que visité hace poco sí usaba markup, pero no lo compilaba a HTML para servirlo estáticamente, sino que lo renderizaba con JavaScript del lado del cliente. WTF.
No solo son verificaciones DDoS como las de Cloudflare; ahora incluso cosas que deberían estar dentro del HTML de la página se cargan con JavaScript.
Cuanto más hostil se vuelve Internet, más correcta se vuelve esa decisión.
No termino de entender cómo este método puede generar más de unos miles de combinaciones únicas.
Tipo de navegador × versión del navegador × versión del sistema operativo × versión del acelerador × … ¿qué más? No parece haber suficiente variación como para decir que sea único de forma remota.
¿Esta técnica toma huellas digitales a partir de diferencias de hardware, drivers y sistema operativo en el procesamiento de audio, o solo observa el software del navegador?
Supongo que hubo, o todavía hay, técnicas similares que exponen diferencias en el dispositivo gráfico subyacente.
Uno de los ejemplos del artículo es la transformada rápida de Fourier (FFT). Todos los sistemas operativos tienen una versión de esta función, pero tiende a optimizarse con el tiempo y a menudo se comporta de forma distinta según la CPU, dependiendo de las instrucciones SIMD disponibles.