Informe WebGL de CreepJS: contextos y señales
Sigue los campos WebGL de CreepJS desde el código fuente fijado hasta el informe: contextos, renderer, píxeles y límites.
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.
Un informe WebGL de CreepJS no es un único valor gráfico ni una sola prueba de aprobado o fallo. En la implementación pública fijada, rutas de código distintas recopilan parámetros de WebGL y WebGL2, metadatos opcionales del renderer, precisión de shaders, datos de imagen del canvas y resúmenes de capacidades derivados. Leer todos esos campos como un solo veredicto oculta qué operación produjo cada uno y qué ruta de error se alcanzó realmente.
BotBrowser documenta el comportamiento de WebGL controlado por perfiles y su verificación, pero no afirma que un informe de CreepJS identifique un dispositivo físico ni prediga la decisión de un sitio ajeno. La tarea útil es más acotada: seguir una implementación identificada desde sus campos de origen hasta sus ramas condicionales del informe, y conservar los límites entre esas observaciones.
BotBrowser permite configurar WebGL mediante perfiles y comprobar de forma autorizada el comportamiento declarado; no puede determinar la identidad de un dispositivo físico ni la decisión de otro sitio a partir de un campo de CreepJS.
Para el recolector distinto de BrowserLeaks, el análisis de su informe WebGL sigue la detección del contexto, los datos opcionales del renderer y las comprobaciones de campos ausentes, sin atribuir esos resultados a CreepJS.
TL;DR
- El archivo revisado es
src/webgl/index.tsdel commit de CreepJS10aa6724cd33a1015db1574211890518cd04f0cc. La inspección estática no demuestra el comportamiento actual del sitio ni constituye una medición de BotBrowser. - La función crea contextos WebGL y WebGL2 por separado. Termina si falta el contexto WebGL, pero la rama visible no exige que WebGL2 esté disponible antes de continuar.
- La comparación espejo contrasta valores seleccionados del mapa de parámetros WebGL2 con valores verdaderos del mapa WebGL. Omite
ALIASED_LINE_WIDTH_RANGE,SHADING_LANGUAGE_VERSIONyVERSION. WEBGL_debug_renderer_info, la precisión de shaders, un URI de datos del canvas y el resultado dereadPixelsson observaciones distintas. La ausencia de datos en un canal no explica otro.- Una rama derivada de capacidades puede asignar
LowerEntropy.WEBGLcuando un valor no aparece en una lista incrustada. Eso describe esta implementación fijada, no una regla WebGL universal ni una afirmación sobre una persona.
Contenido
- Dos contextos inician rutas de recopilación separadas
- La comparación espejo tiene una cobertura condicional
- Los campos del renderer y de precisión no son intercambiables
- La exportación del canvas y la lectura de píxeles pueden divergir
- Los resúmenes de capacidad son una derivación posterior
- La lectura del informe debe respetar los límites de la evidencia
- Conclusión práctica
Dos contextos inician rutas de recopilación separadas
El código crea un canvas para el contexto webgl y otro para webgl2, y llama a getContext con los nombres correspondientes. La función comprueba si existe el primer contexto. Si no existe, CreepJS registra un resultado de prueba webgl fallido y sale de esta ruta. En ese punto el código no realiza una salida temprana equivalente para gl2; los helpers posteriores tratan de otra manera un contexto ausente.
Ese orden importa al leer un informe compacto. Una ruta WebGL fallida no significa que ambos tipos de contexto se hayan probado correctamente y hayan devuelto resultados coincidentes. El origen tampoco explica por qué no estuvo disponible el primer contexto. La creación puede depender del soporte del navegador, del estado del canvas, de condiciones de recursos y del código de la aplicación. El campo del informe no identifica cuál de esas explicaciones corresponde.
La distinción resulta útil en una página de diagnóstico propia. Un recolector puede registrar por separado webgl_context_created y webgl2_context_created, y conservar aparte un error si la configuración produce una excepción. No debería escribir un único booleano graphics_supported antes de que cada intento tenga un resultado definido. Esta forma de registro propuesta es una ayuda de lectura del lado de la aplicación; no es un esquema de salida de CreepJS ni una API estándar del navegador.
| Evento de recopilación | Qué establece el código fijado | Qué sigue sin saberse |
|---|---|---|
| Falta el contexto WebGL | Esta función registra una prueba webgl fallida y detiene esta ruta | Por qué la solicitud no produjo un contexto, o si un nuevo intento sería distinto |
| Existe WebGL; falta WebGL2 | La ruta supera la primera comprobación; los helpers que reciben el contexto ausente pueden devolver datos vacíos o indefinidos | Si los campos posteriores del informe conservan esa diferencia para un consumidor concreto |
| Existen ambas referencias a contextos | Se pueden llamar los helpers posteriores de parámetros y renderizado con ambas referencias | Si todas las extensiones opcionales y operaciones de lectura tendrán éxito |
| La configuración falla antes de asignar un campo | El manejo de errores externo puede devolver un resultado con forma de error | Qué operación falló, salvo que se conserve la etapa junto con el error |
Este es un mapa de flujo de control, no una matriz de compatibilidad. Tener un contexto disponible no implica que exista toda extensión opcional, y crear el contexto correctamente no garantiza que el buffer dibujado pueda leerse. Una aplicación que compara versiones de navegador debería nombrar el contexto solicitado, el resultado de la llamada y cada operación posterior por separado. Así, un cambio en el código de recopilación resulta visible en lugar de disfrazarse como un cambio de capacidad gráfica.
La visión general de fingerprinting WebGL cubre la superficie de divulgación más amplia y los controles de perfiles de BotBrowser. El módulo fijado src/webgl/index.ts construye por separado los resultados de contexto, las comparaciones de parámetros, los metadatos renderer opcionales, la precisión de shaders, las salidas canvas y de píxeles, y los campos de capacidad derivada. El análisis de estados cuando falta el renderer WebGL cubre estados del lado de una aplicación, como un campo no solicitado, un contexto no disponible o perdido y una extensión no disponible; no recorre el ensamblaje de resultados de CreepJS.
La comparación espejo tiene una cobertura condicional
Después de crear objetos de parámetros para los dos contextos, la implementación define tres claves que se excluyen de la comparación espejo: ALIASED_LINE_WIDTH_RANGE, SHADING_LANGUAGE_VERSION y VERSION. La lista de diferencias se obtiene de las claves del objeto WebGL2. Cada candidata también debe tener un valor verdadero en el objeto WebGL, no ser uno de los nombres excluidos y presentar una representación de texto distinta en ambos objetos. La rama del informe solo se ejecuta cuando la lista resultante no está vacía.
La condición se puede representar sin atribuirle más alcance del que tiene:
para cada clave del objeto de parámetros WebGL2:
conservarla solo si WebGL[key] es verdadera
omitir ALIASED_LINE_WIDTH_RANGE, SHADING_LANGUAGE_VERSION, VERSION
comparar String(WebGL[key]) con String(WebGL2[key])
informar una diferencia solo si queda al menos una clave
Es una guía útil para revisar el código porque muestra tanto la cobertura como las omisiones. No es una comprobación exhaustiva de igualdad de todos los valores expuestos por ambos contextos. No se recorre una propiedad presente solo en el objeto WebGL. Un valor falso en WebGL no supera la condición de verdad. Una diferencia que la conversión a texto oculta puede compararse de forma distinta a una comparación estructural de matrices o valores tipados. Los tres nombres excluidos quedan fuera de esta comprobación con independencia de sus valores.
| Forma de entrada de ejemplo | ¿Se incluye en la lista de diferencias del código? | Motivo |
|---|---|---|
| El mismo valor verdadero para una clave no excluida en ambos mapas | No | Las representaciones de texto coinciden |
| Valores verdaderos distintos para una clave no excluida en ambos mapas | Sí | Las representaciones de texto difieren |
El valor WebGL es 0, false, '', null o undefined | No | El filtro exige que el valor del lado WebGL sea verdadero |
| La clave no aparece en el mapa WebGL2 | No | La implementación recorre las claves WebGL2 |
La clave es VERSION u otro de los dos nombres excluidos | No | El mapa de exclusiones explícito la filtra |
Estos casos describen el predicado visible en el código fijado; no afirman qué devolvió un navegador concreto. Se puede reproducir el razonamiento consultando el objeto VersionParam, el filtro Object.keys(params2) y la condición mismatch.length en las líneas del commit indicado. La distinción evita una lectura excesiva habitual: «el informe no mostró diferencias» no significa que todas las salidas WebGL y WebGL2 fueran iguales. Solo significa que ese predicado produjo una lista vacía para los datos que recibió.
El informe tampoco indica a quien mantiene una aplicación si la diferencia procede de un defecto de implementación, valores no compatibles, serialización, un contexto ausente o un cambio en la recopilación. Son posibles líneas de investigación, no conclusiones contenidas en la rama. Si importa la causa, el registro de diagnóstico debería conservar el nombre del campo y la etapa de recopilación; un recuento agregado de «diferencias WebGL» descarta justo la evidencia necesaria para distinguir los casos.
Los campos del renderer y de precisión no son intercambiables
El origen recopila primero los valores de parámetros de cada contexto. Después añade información no enmascarada del renderer cuando WEBGL_debug_renderer_info está disponible. El helper solicita esa extensión al contexto; si no la recibe, devuelve un objeto vacío. Si está disponible, consulta UNMASKED_VENDOR_WEBGL y UNMASKED_RENDERER_WEBGL mediante getParameter.
Esa ruta de extensión opcional es distinta de los parámetros normales del contexto. La especificación de la extensión de Khronos define las constantes opcionales de vendor y renderer no enmascarados; la referencia de MDN getParameter describe la API de consulta. Ninguna de las dos fuentes convierte la ausencia del objeto de extensión en una explicación causal. No prueba una configuración de privacidad, la falta de una GPU, una decisión de política ni la intención de la aplicación. Significa que el helper no añadió esos dos campos por esta ruta.
La precisión de shaders es otra categoría. El helper solicita varios formatos para shaders de vértice y fragmento, incluidos formatos de coma flotante de precisión baja, media y alta, además de precisión alta para enteros. Luego escribe las propiedades precision, rangeMax y rangeMin bajo claves asociadas a la etapa del shader y al formato. Esos campos describen la respuesta de la consulta de precisión del contexto actual. No son nombres de renderer, indicadores de extensión ni prueba de que dos dispositivos sean físicamente idénticos.
El objeto de parámetros final añade además atributos y límites seleccionados del contexto. El ensamblaje visible incluye el atributo antialias, MAX_VIEWPORT_DIMS, la anisotropía máxima de textura si se encuentra una extensión de anisotropía y MAX_DRAW_BUFFERS_WEBGL si está disponible su extensión. Algunas consultas se envuelven en un helper attempt, mientras que los valores que dependen de extensiones pueden estar ausentes. Quien consuma el informe debería mantener «no presente», «no consultado» y «la consulta produjo un error» como estados separados cuando la salida circundante conserve esa diferencia.
| Familia de salida | Operación del origen | Lo que un valor ausente no establece |
|---|---|---|
| Parámetros estándar | Enumerar los nombres de parámetros seleccionados y llamar a getParameter | Que el navegador carezca de todas las capacidades gráficas |
| Vendor/renderer no enmascarados | Solicitar WEBGL_debug_renderer_info y consultar dos constantes | Que una configuración de privacidad causara la ausencia |
| Precisión de shaders | Llamar a getShaderPrecisionFormat para formatos nombrados | Una identidad de dispositivo estable o un veredicto de un sitio |
| Límites opcionales | Solicitar constantes dependientes de extensiones o atributos del contexto | Si otra consulta independiente tendría éxito |
La tabla trata deliberadamente de la ruta del código, no de un esquema de seguimiento recomendado. Las cadenas de renderer pueden identificar y no siempre hacen falta para resolver una pregunta de soporte. Un producto debería recopilar solo los datos que necesite su tarea declarada, explicar los diagnósticos opcionales y evitar usar una etiqueta sin procesar como clave de cuenta. La documentación WebGL de BotBrowser describe los ajustes propios de BotBrowser controlados por perfiles; el código de CreepJS no demuestra que BotBrowser devuelva un valor específico en el equipo de una persona.
La exportación del canvas y la lectura de píxeles pueden divergir
El helper getWebGLData dibuja un patrón en un contexto e intenta producir dos familias de salida. Una es un URI de datos del canvas. La otra es una matriz de bytes rellenada con readPixels. El código lee las dimensiones del buffer de dibujo, obtiene un ancho y alto menores dividiéndolos entre 15 y 6, reserva cuatro bytes por píxel muestreado y luego solicita valores RGBA sin signo de 8 bits desde el origen inferior izquierdo.
El orden crea un caso concreto de fallo parcial. La función intenta toDataURL antes de readPixels. Si la llamada interna a readPixels lanza una excepción, el catch devuelve el dataURI ya obtenido y asigna undefined a pixels. El resultado no es todo o nada. Quien vea un valor de imagen junto a datos de píxeles ausentes no debería concluir que falló toda la ruta WebGL. A la inversa, un URI de datos ausente no prueba que se intentara leer píxeles: un error anterior puede llegar primero al catch externo.
El helper también trata de forma especial un OffscreenCanvas: crea un canvas normal para la operación del URI de datos y dibuja allí. La lectura de píxeles sigue vinculada al contexto WebGL original. Por eso la ruta de exportación de imagen y la de píxeles están relacionadas por el dibujo, pero no son literalmente la misma llamada de API ni la misma representación de salida.
| Punto de fallo | Ruta del URI de datos | Ruta de píxeles | Límite de interpretación |
|---|---|---|---|
| Falta el argumento del contexto | El helper devuelve campos de salida indefinidos | No se realiza una lectura | Este helper no explica por qué falta el contexto |
| Falla el dibujo o la creación del URI | El manejo externo captura un error | No se llega a la lectura posterior | No lo clasifiques como fallo de readPixels |
readPixels falla tras crear un URI | El helper puede devolver el URI de datos | pixels queda como undefined | Los dos campos no comparten un indicador atómico de éxito |
| Ambas operaciones devuelven datos | Hay un URI de datos | Se devuelve una matriz de píxeles | Ningún valor describe por sí solo un dispositivo físico |
Una persona que mantenga una página de renderizado propia puede usar este mapa para escribir una prueba de soporte: registrar si se ejecutó el dibujo, si terminó la serialización y si terminó la lectura de píxeles. Conviene mantener las salidas separadas para evaluar una alternativa sin conservar más datos de los necesarios para la pregunta de soporte. No se afirma que la cuadrícula de muestra sea una huella estandarizada, que sea única ni que una de las salidas prediga si un tercero aceptará una sesión.
Los resúmenes de capacidad son una derivación posterior
Después de recopilar los campos de origen, el módulo crea una lista numérica normalizada con valores de nivel superior que pasan la condición truthy de JavaScript y no son cadenas. Array.prototype.flat() aplana un nivel de arrays; cada elemento resultante se convierte con Number, se eliminan duplicados y se ordena numéricamente el resultado. Después usa la cadena del renderer para derivar una marca de GPU y calcula dos resúmenes distintos: un valor compacto a partir de la marca y el vector de parámetros, y un valor de capacidad basado en una reducción sobre la lista numérica.
El módulo compara esos valores derivados con listas incrustadas. Si existe un valor de marca y capacidades, pero no aparece en la lista de marcas, la condición hasSusGpu es verdadera. Si existe el valor de capacidad derivado pero no figura en la lista numérica, hasSusCapabilities es verdadera. Cualquiera de esas ramas puede asignar LowerEntropy.WEBGL y llamar a sendToTrash con una etiqueta correspondiente. Más tarde, el origen registra la prueba WebGL como superada y devuelve los datos recopilados con campos de clasificación de GPU.
La palabra «sospechoso» en el nombre de una variable pertenece a la rama interna de la implementación. No es una definición estandarizada de hardware sospechoso. Un valor fuera de una lista del origen puede deberse a cambios en la lista, una combinación no representada, un parámetro ausente o transformado, o el entorno de ejecución. La lectura estática no permite saber cuál de esas opciones describe un navegador que genera un informe actualmente.
| Elemento derivado | Entradas visibles en el código | Lo que la rama no demuestra |
|---|---|---|
webglParams | Valores de nivel superior truthy que no son cadenas; arrays aplanados un nivel, convertidos a números, sin duplicados y ordenados | Que estén presentes todos los parámetros WebGL o que el vector sea estable entre versiones |
webglBrandCapabilities | Una marca derivada del renderer más la forma textual del vector de parámetros | Que la cadena del renderer nombre hardware físico o que el valor derivado identifique un dispositivo de forma única |
webglCapabilities | Valores numéricos de parámetros y sus posiciones ordenadas dentro de una reducción | Que el resultado sea un identificador de capacidades estándar del sector |
Rama LowerEntropy.WEBGL | Pruebas de pertenencia a listas incrustadas de marcas y capacidades | Un veredicto universal de bot, la identidad de una cuenta o la causa de una política |
Hay una diferencia importante entre campos sin procesar y un resumen derivado. Un campo de origen se puede asociar a una llamada de la API WebGL. Un resumen puede depender de normalización, ordenación, funciones de valor compacto, listas de consulta y comprobaciones de verdad posteriores a la recopilación. Si cambia el informe final, primero conviene comparar la revisión del código y esas transformaciones en lugar de atribuir el cambio a una GPU física.
El análisis de grupos de señales de CreepJS describe cómo un informe agrupa superficies independientes del navegador. El análisis de decisiones entre grupos cubre combinaciones y lógica de decisión. La rama derivada del módulo usa sus campos WebGL recopilados y sus listas integradas; por sí sola no describe la agregación entre grupos.
La lectura del informe debe respetar los límites de la evidencia
Una revisión disciplinada del código empieza por fijar la revisión. La misma ruta en una rama principal que cambia puede modificarse entre un informe guardado y el día de hoy. Fijar el commit 10aa6724cd33a1015db1574211890518cd04f0cc y la ruta src/webgl/index.ts hace reproducibles las referencias a líneas y las descripciones del flujo de control. Aun así, no demuestra que un sitio activo haya desplegado esa revisión, que un informe concreto se generara con ella ni que todas sus rutas se ejecutaran en un navegador específico.
Para revisar un informe, registra solo los hechos necesarios para responder la pregunta:
- Identifica el campo visible y su familia de salida: contexto, parámetro, extensión opcional, consulta de shader, URI de datos, matriz de píxeles o resumen derivado.
- Relaciona el campo con una función y una rama del código fijado antes de asignarle una causa.
- Conserva los estados ausente, indefinido, vacío, error y presente por separado cuando el origen o el informe los expongan.
- Comprueba si un valor se comparó directamente, se convirtió a texto, se normalizó, se cambió o se contrastó con una lista.
- Expresa el resultado acotado que respalda la rama observada y deja sin resolver las causas no observadas.
Estos pasos forman un procedimiento de interpretación útil para revisar privacidad, analizar regresiones y explicar un informe de terceros sin inventar una identidad de dispositivo. Una instantánea del código fuente muestra qué haría el código con entradas determinadas; no aporta esas entradas ni demuestra que se ejecutara una rama no observada.
Preguntas frecuentes
¿Un renderer WebGL ausente significa que WebGL está desactivado?
No. Los campos del renderer llegan a través de la extensión opcional WEBGL_debug_renderer_info, mientras que la creación del contexto se comprueba por separado. La ruta puede tener un contexto sin añadir valores no enmascarados del renderer. Los campos ausentes no identifican por sí solos la explicación.
¿La comparación espejo compara todos los valores WebGL?
No. Recorre las claves del objeto de parámetros WebGL2, exige un valor WebGL correspondiente que sea verdadero, omite tres claves concretas y compara representaciones de texto. Una lista vacía de diferencias se limita a ese predicado y a los datos recibidos.
¿LowerEntropy.WEBGL es un veredicto de que el navegador es un bot?
El módulo fijado asigna esa marca interna cuando uno de sus valores derivados no aparece en listas incrustadas. El código no la convierte en un estándar universal de WebGL y ese campo por sí solo no demuestra la decisión de un sitio sobre un visitante.
¿Un URI de datos correcto significa que readPixels también funcionó?
No. El helper intenta serializar antes de leer los píxeles. La captura interna del fallo puede devolver un URI de datos junto con datos de píxeles indefinidos. Esos campos tienen estados de finalización distintos.
Fuentes
- Implementación WebGL de CreepJS fijada al commit
10aa6724cd33a1015db1574211890518cd04f0cc - Especificación WebGL 1.0 de Khronos
- Extensión
WEBGL_debug_renderer_infode Khronos - MDN:
WebGLRenderingContext.getParameter() - MDN:
HTMLCanvasElement.toDataURL() - Documentación WebGL de BotBrowser
- Documentación de consistencia de automatización de BotBrowser
Conclusión práctica
Interpreta el informe como un conjunto de observaciones dependientes del código fuente, no como una etiqueta de dispositivo única. Fija la revisión de la implementación, conserva por separado el contexto y la operación que generaron cada valor, y no mezcles los datos opcionales del renderer, la serialización de la imagen, la lectura de píxeles y las ramas derivadas de capacidades. Si falta un campo, describe su ausencia al nivel que respalda el código; no infieras la causa ni la decisión de otro sitio.
Este artículo forma parte de la guía: ¿Qué es la huella digital del navegador?
Artículos Relacionados
Informe WebGL de BrowserLeaks: etapas y datos ausentes
Huella digitalWEBGL_debug_renderer_info: límites de privacidad y del renderer
Huella digitalRenderizador WebGL ausente: privacidad o contexto
Huella digitalwebgl_debug_renderer_info: qué revela tu GPU a las páginas
Huella digitalRenderizado WebGL por software, capacidades y privacidad
Huella digitalSeñales Math de CreepJS: leer los campos
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.