Predicción CreepJS: agregación y estados desconocidos
Compara la búsqueda getPrediction de CreepJS con la agregación de señales en renderPrediction y los estados unknown; no prueban la identidad de un dispositivo.
BotBrowser Team
Quieres la documentación estructurada de Huella digital?
Este artículo forma parte de la biblioteca editorial. Para pasos de configuración, material de referencia y actualizaciones continuas, entra en la sección de docs.
BotBrowser puede mantener coherente un perfil declarado entre superficies visibles para el navegador, pero no puede certificar una predicción colectiva de terceros. En el código fijado de CreepJS, getPrediction() busca una fila de datos colectivos y selecciona candidatos, mientras que renderPrediction() lee por separado decryptionData, agrega campos de señales y muestra estados de revisión o puntuación. Son rutas distintas del código; ninguna de sus salidas prueba la identidad de una persona o máquina ni que el navegador sea un bot.
TL;DR
getPredictionbusca en los datos proporcionados una fila cuyoidcoincida con el hash solicitado, también tras convertir ambos valores a cadenas. La variable local llamadadecryptedes la clave del objeto coincidente; esta función no descifra la fila.- Los campos de sistema, GPU y marca de GPU solo se devuelven cuando sus listas de candidatos contienen exactamente un valor. Un dispositivo también puede devolverse si varios nombres comparten una misma base.
- El renderizador reduce valores de 18 registros de recopiladores con nombre a tres objetos JavaScript
Setpara marca de GPU, GPU y dispositivo.Setelimina duplicados y el código elimina despuésundefined; esta agregación no conserva qué recopilador aportó cada valor que queda. unknownHTML,pendingReview, las calificaciones de mezcla colectiva, los marcadores de predicción y el marcador de error son ramas distintas. Ninguna es una probabilidad calibrada de que la etiqueta sea correcta.
Contents
- Una etiqueta de predicción es una salida agregada
- Emparejar la fila colectiva antes de leer sus campos
- El número de candidatos determina qué valores se devuelven
- Dieciocho registros alimentan tres conjuntos sin duplicados
- Separar la selección del dispositivo de los estados de puntuación
- Conservar un registro de comparación ligado a la fuente
- Practical conclusion
Una etiqueta de predicción es una salida agregada
La palabra «predicción» puede invitar a una interpretación más fuerte de lo que permite la implementación. Alguien puede ver un nombre de dispositivo junto a una puntuación y suponer que la página identificó un dispositivo físico o midió la probabilidad de que el nombre sea correcto. La implementación fijada de CreepJS no respalda ninguna de esas conclusiones. Muestra cómo se seleccionan y presentan determinados valores a partir de sus entradas; la fuente no aporta un estudio de calibración, un intervalo de confianza ni un identificador a nivel de persona.
Dos funciones responden a preguntas diferentes. getPrediction busca una fila de datos colectivos y reduce cuatro listas de candidatos a los campos system, device, gpu y gpuBrand. renderPrediction recibe objetos de recopiladores, combina campos seleccionados entre ellos y construye después el marcado de la zona de predicción y de las filas de señales individuales. El resultado de la búsqueda y el resumen renderizado de los recopiladores no deben tratarse como una única puntuación opaca.
La guía de grupos y mentiras de CreepJS explica cómo leer etiquetas por superficie, mientras que el análisis de comprobaciones cruzadas sigue los patrones ordenados detrás de botHash. Esos temas no trazan la coincidencia de la fila colectiva ni las ramas de candidatos y visualización del panel de predicción.
La distinción importa cuando cambia un informe. Una etiqueta puede desaparecer porque una lista de candidatos ahora tiene dos valores, porque los valores de los recopiladores ya no comparten una base, porque no se proporcionó un campo o porque la predicción tomó su rama de error. Esas rutas tienen significados diferentes. La ausencia de un valor único no demuestra que el navegador carezca de GPU, y un marcador de error no demuestra que todos los recopiladores se ejecutaran y discreparan.
El alcance se limita a la revisión fijada 10aa6724cd33a1015db1574211890518cd04f0cc de src/prediction/index.ts de CreepJS, no a una observación actual del servicio activo. El material general de /docs/proof/fingerprinting-privacy-threat/ describe señales de huella del navegador, pero no traza las ramas de este módulo de predicción.
Emparejar la fila colectiva antes de leer sus campos
getPrediction recibe hash y data. Recorre las claves de data, busca en el array almacenado en cada clave y compara el id de cada elemento con el hash solicitado. La comparación acepta tanto igualdad directa como igualdad después de convertir ambos valores a cadenas. La clave que contiene el elemento coincidente se guarda en una variable local llamada decrypted.
Ese nombre de variable no demuestra que haya criptografía. En esta función, la operación relevante es una búsqueda en un array y una comparación de identificadores. La fuente no descifra aquí el elemento. La descripción precisa es «búsqueda de fila colectiva por hash», no «descifrado de la predicción». El nombre de una variable local no cambia la operación realizada por el código.
Cuando encuentra un elemento coincidente, la función copia cuatro arrays a variables locales: devices, systems, gpus y gpuBrands. Si falta un array, se usa uno vacío. El objeto de resultado selecciona después un valor público de cada lista. Por tanto, la búsqueda puede tener éxito mientras uno o más campos devueltos siguen siendo undefined: encontrar una fila y encontrar un valor no ambiguo son pasos separados.
| Valor de origen | Operación de búsqueda | Interpretación prudente |
|---|---|---|
item.id | Compararlo con el hash proporcionado, también admitiendo igualdad tras convertir a cadena | Se encontró un registro coincidente dentro del objeto de datos proporcionado. |
item.systems | Usar una lista vacía si falta; devolver un sistema solo si hay un candidato | Cero o varios candidatos no producen un valor system único. |
item.gpus | Usar una lista vacía si falta; devolver una GPU solo si hay un candidato | Que no aparezca una GPU no afirma que falte una GPU en el navegador. |
item.gpuBrands | Usar una lista vacía si falta; devolver una marca solo si hay un candidato | La función no clasifica varias marcas ni asigna una confianza a una de ellas. |
item.devices | Usar una lista vacía si falta; devolver un candidato o una base compartida | Un prefijo textual común es una regla de selección, no una verificación independiente del hardware. |
La última fila es especialmente fácil de sobreinterpretar. El comentario del código usa Android 10 como base compartida por Android 10 y Android 10 Blah Blah. Ese ejemplo documenta una regla de contención entre cadenas. No demuestra que CreepJS confirmara una versión exacta del sistema operativo en un navegador activo.
El número de candidatos determina qué valores se devuelven
Las reglas de retorno son deliberadamente asimétricas. Tres campos exigen un único candidato; device tiene además una alternativa basada en una base compartida. La longitud del array explica por qué un campo visible puede faltar aunque exista la fila colectiva.
| Campo | Condición de candidato en el código fijado | Valor devuelto si no se cumple |
|---|---|---|
system | systems.length == 1 | undefined |
gpu | gpus.length == 1 | undefined |
gpuBrand | gpuBrands.length == 1 | undefined |
device | Un dispositivo, o un nombre base incluido en todas las cadenas candidatas | El ayudante de base común devuelve undefined si ningún nombre se comparte entre todas. |
Para sistemas, modelos de GPU y marcas de GPU, la implementación no elige el candidato más frecuente ni ordena los candidatos por una puntuación. Comprueba si el array tiene un elemento. Si no es así, el campo es undefined. Es un límite explícito de ambigüedad, no una clasificación oculta.
Para los dispositivos, getBaseDeviceName busca una cadena candidata a tal que todas las cadenas candidatas b incluyan a. Si solo hay un candidato, el código lo devuelve directamente antes de llamar al ayudante. Si hay varios, puede devolverse una base compartida; si ninguna aparece en todos, esta rama no produce un único nombre. La regla es textual y no debe describirse como un cálculo de distancia entre dispositivos.
Estos ejemplos derivados de la fuente muestran la rama de código, no un informe activo:
| Lista de candidatos | Resultado de la ruta de código | Lo que el resultado no demuestra |
|---|---|---|
systems tiene una entrada | Esa entrada se devuelve como system | Que la etiqueta identifique el sistema operativo de una persona. |
gpus tiene dos entradas | No se devuelve un único valor gpu | Que ambas GPU estuvieran ausentes de todos los recopiladores. |
devices contiene Android 10 y Android 10 Blah Blah | Puede devolverse la base común Android 10 | Que una versión concreta de Android se verificara de forma independiente. |
devices contiene nombres no relacionados sin una base común a todos | El ayudante de base devuelve ningún valor | Que el navegador sea inválido o automatizado. |
Conviene conservar el resultado undefined. Sustituirlo por el primer candidato, una conjetura mayoritaria o un dispositivo inferido inventaría una regla de selección que esta función no implementa. Una hoja de comparación debe registrar «no se devolvió un valor único» por separado de «el campo de origen no estaba presente».
Dieciocho registros alimentan tres conjuntos sin duplicados
Los campos agregados gpuSystem y gpuModelSystem no describen la creación de contextos WebGL ni la compatibilidad con extensiones; el análisis del informe WebGL de CreepJS examina por separado las señales de contexto y capacidades del renderizador.
renderPrediction lee objetos de señales con nombre y construye tres instancias de Set. Cada conjunto recibe una propiedad de 18 registros: jsRuntime, emojiSystem, domRectSystem, svgSystem, mimeTypesSystem, audioSystem, canvasSystem, canvasPaintSystem, canvasTextSystem, canvasEmojiSystem, textMetricsSystem, webglSystem, gpuSystem, gpuModelSystem, fontsSystem, voicesSystem, screenSystem y deviceOfTimezone.
Las propiedades se proyectan por separado. Un conjunto recoge gpuBrand, otro recoge gpu y un tercero recoge device. Cada registro se protege con un objeto vacío alternativo antes de leer la propiedad. Después de construir cada conjunto, el código elimina undefined. Los valores iguales repetidos se reducen a uno porque Set almacena valores únicos.
| Conjunto agregado | Propiedad leída de cada uno de los 18 registros | Transformación directa visible en la fuente |
|---|---|---|
gpuBrands | .gpuBrand | Construir un conjunto y eliminar después undefined. |
gpus | .gpu | Construir un conjunto y eliminar después undefined. |
devices | .device | Construir un conjunto y eliminar después undefined. |
Esta operación reduce una colección de campos con nombre a valores únicos, pero el conjunto resultante no indica qué recopilador aportó cada valor. Si cinco recopiladores aportan el mismo gpuBrand, el conjunto contiene un valor, no un recuento de cinco. Si dos recopiladores discrepan, el conjunto puede contener dos valores, pero la pantalla tampoco señala qué API produjo cada uno. El módulo ascendente conserva la lista de fuentes en el código; si la procedencia importa para una comparación, debe guardarse en un registro separado.
El conjunto tampoco equivale a la lista de candidatos de la fila colectiva. Los arrays candidatos de getPrediction responden a si puede devolverse un valor único para un hash. Los conjuntos de recopiladores de renderPrediction combinan valores de objetos de señales para un resumen visible. Usar «consenso» para ambas rutas ocultaría esa diferencia.
Los 18 campos de origen pueden agruparse por la superficie que nombran, pero esas etiquetas no implican igual calidad ni independencia. Canvas de imagen, pintura, texto y emoji son entradas separadas en el código. También lo son gpuSystem y gpuModelSystem. Tratarlos como votos plenamente independientes añadiría una suposición estadística que la implementación no contiene.
Separar la selección del dispositivo de los estados de puntuación
Antes de renderizar la etiqueta del dispositivo, la interfaz calcula una selección especial de Windows Remote Firefox Privacy. La fuente cuenta cuántas cadenas de dispositivo contienen «Windows» y divide ese recuento por el total de cadenas. Solo cuando la proporción supera 0.5, esta rama prueba una secuencia fija de preferencias: Windows 7, Windows 8, Windows 8.1, Windows 11 y, por último, Windows 10; para cada versión comprueba primero la variante de 64 bits y luego la forma más corta. Si la proporción no supera la mitad, el ayudante devuelve undefined.
El deviceName final es el resultado del ayudante RFP o, si ese resultado es falsy, el nombre base común de los dispositivos. El comentario dice que los datos de muestra ignoran Firefox RFP porque devuelve Windows 10, y explica el orden preferido cuando aparecen varias versiones de Windows. Es una regla de presentación específica de la fuente. No demuestra que la población general siga ese orden ni debe presentarse como un detector de sistema operativo generalmente preciso.
crowdBlendingScoreGrade asigna letras a intervalos numéricos: A desde 90, B desde 80, C desde 70, D desde 60 y F por debajo de 60. El marcado muestra porcentaje y letra solo si crowdBlendingScore tiene tipo JavaScript number. Una rama bot separada muestra «locked». El código define un mapeo de calificaciones y condiciones de interfaz; no establece qué predice la puntuación ni cómo se calibra.
El módulo presenta pendingReview como una nota separada cuando el campo es truthy. Esa etiqueta debe registrarse por separado de la puntuación y del nombre predicho. La fuente fijada no justifica sustituirla por «falló», «aprobado» o «revisión humana completada» sin otra fuente que defina exactamente ese estado.
Varios detalles de visualización pueden registrarse sin convertirlos en afirmaciones de confianza:
| Estado visible | Condición de origen | Lectura acotada |
|---|---|---|
** antes de la etiqueta combinada | deviceName y gpuBrandName son truthy | El renderizador dispone de ambas cadenas. Los asteriscos no son una probabilidad. |
* antes de una etiqueta | Solo una de esas cadenas de visualización es truthy | Esta rama dispone de una de las dos cadenas. |
| Iconos de predicción en blanco | Ninguna cadena es truthy | Esta rama no muestra la etiqueta combinada. |
pending review: … | pendingReview es truthy | Se muestra el campo proporcionado; la fuente fijada no define el resultado de revisión. |
| Puntuación y letra de mezcla colectiva | La puntuación tiene tipo number y la rama de bloqueo no se cumple | La interfaz muestra el número proporcionado y una banda de calificación; la precisión es desconocida. |
locked | La rama bot es truthy | La interfaz usa la rama de bloqueo y no muestra allí la puntuación. |
El ayudante hasValue necesita una cautela adicional. Busca el primer valor de propiedad cuyo tipo no sea undefined; las llamadas lo niegan para elegir unknownHTML. Un valor definido false o 0 también es falsy, por lo que puede entrar en la rama de visualización desconocida. Ese comportamiento de la fuente significa que una etiqueta «unknown» no demuestra que el recopilador no se ejecutara. Puede reflejar cómo este ayudante trata un valor falsy. La afirmación se limita a la implementación fijada y debe revisarse si una versión posterior cambia el ayudante.
predictionErrorPatch es otra rama. Cuando se llama con un error y existe el elemento de predicción, renderiza «Prediction Failed» e iconos en blanco en muchas filas. Ese marcador describe la interfaz de error, no la regla de recuento de candidatos ni una ejecución correcta en la que faltaran todas las señales. El registro debe separar la rama de error de un informe normal cuyas filas individuales aparezcan como desconocidas.
Conservar un registro de comparación ligado a la fuente
Cuando dos informes difieran, registra primero la pregunta y la revisión de la fuente antes de interpretar las etiquetas. Estos campos conservan las distinciones de la implementación sin copiar un hash sin procesar ni recopilar una identificación completa del navegador:
| Campo del registro | Qué conservar | Por qué importa |
|---|---|---|
| Fuente | Repositorio, SHA del commit y ruta del archivo | Una revisión posterior puede cambiar la búsqueda o el renderizado. |
| Estado de búsqueda | Si los datos suministrados contenían una fila cuyo hash coincidía; no guardes el hash | La presencia de una fila y la unicidad de un campo son resultados separados. |
| Número de candidatos | Recuentos de sistemas, dispositivos, GPU y marcas de GPU | Las reglas de retorno dependen de la longitud del array y de una base de dispositivo compartida. |
| Estado de agregación | Qué campos de recopiladores con nombre estaban presentes y si cada conjunto tenía cero, uno o varios valores únicos | Un conjunto deduplicado no conserva la lista original de contribuidores. |
| Estado de renderizado | Marcador de predicción, rama unknown, pendingReview, puntuación numérica, bloqueo o marcador de error | Zonas vacías visualmente similares pueden proceder de rutas distintas. |
| Límites | Si la nota es una lectura de fuente fijada, una observación actual de página u otra fuente acotada de forma explícita | El código fuente por sí solo no demuestra la salida actual del servicio ni su precisión. |
No guardes el hash proporcionado solo porque la búsqueda lo use. Normalmente basta con responder «¿había una fila coincidente?» con un booleano y los recuentos candidatos. Conservar un identificador sin procesar ampliaría los datos retenidos sin mejorar la explicación de la rama.
Usa esta hoja para interpretar y comparar el comportamiento de fuentes públicas. No es un protocolo para reproducir el backend de CreepJS, una evaluación de precisión ni un método para cambiar la puntuación de un tercero. Esas afirmaciones requieren pruebas distintas de las que aporta este archivo de código.
Sources
- Módulo de predicción de CreepJS en el commit
10aa6724cd33a1015db1574211890518cd04f0cc: búsqueda, reducción de candidatos, agregación, estados unknown, puntuación y marcador de error. - BotBrowser: riesgos de huella y privacidad: contexto general de señales y privacidad, no la implementación de predicción de CreepJS.
- BotBrowser: coherencia de automatización: cómo considerar conjuntamente las superficies de configuración visibles para el navegador; no establece la decisión de un detector de terceros.
Practical conclusion
Lee el panel de predicción de CreepJS como un conjunto de salidas dependientes de la fuente. Primero confirma si los datos colectivos contienen una fila coincidente; después conserva por separado los recuentos candidatos, los valores únicos de los recopiladores y el estado de visualización. Un valor único devuelto, una base de dispositivo compartida, una banda de puntuación, una nota de revisión pendiente y un marcador desconocido no son pruebas intercambiables. El código fijado explica cómo se ensamblan estas etiquetas; no las convierte en una identidad de dispositivo verificada ni en un juicio calibrado de bot.
Este artículo forma parte de la guía: ¿Qué es la huella digital del navegador?
Artículos Relacionados
Señales Math de CreepJS: leer los campos
Huella digitalInforme WebGL de CreepJS: contextos y señales
Huella digitalInforme WebGL de BrowserLeaks: etapas y datos ausentes
Huella digitalMétricas emoji de CreepJS: conjuntos y sumas
Huella digitalInformes de audio CreepJS: renderizado y valores ausentes
Huella digitalFuentes de CreepJS: 51 nombres y 14 retornos posibles
Lleva BotBrowser de la investigación a producción
Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.