Recopila registros de huellas dactilares
Versión del analizador: 1.0
En este documento, se explica cómo configurar Fingerprint (anteriormente FingerprintJS) para enviar registros a Google Security Operations a través de webhooks.
Fingerprint es una plataforma de inteligencia de dispositivos que proporciona capacidades de identificación de visitantes y detección de fraudes. Genera identificadores de visitantes únicos y proporciona indicadores inteligentes, como la detección de bots, la detección de VPN, la detección del modo incógnito y otras estadísticas de inteligencia del dispositivo. Cuando se identifica a un visitante a través del agente de JavaScript de FingerprintJS, los webhooks pueden enviar los datos del evento de identificación a Google Security Operations en tiempo real.
Antes de comenzar
Asegúrate de cumplir con los siguientes requisitos previos:
- Una instancia de Google SecOps
- Cuenta de FingerprintJS con compatibilidad con webhooks
- Acceso a la Google Cloud Console (para la creación de claves de API)
- Agente de JavaScript de FingerprintJS instalado en tu sitio web o aplicación
Crea un feed de webhook en Google SecOps
Crea el feed
- Ve a Configuración de SIEM > Feeds.
- Haz clic en Agregar feed nuevo.
- En la siguiente página, haz clic en Configurar un solo feed.
- En el campo Nombre del feed, ingresa un nombre para el feed (por ejemplo,
FingerprintJS Identification Events). - Selecciona Webhook como el Tipo de origen.
- Selecciona FingerprintJS como el Tipo de registro.
- Haz clic en Siguiente.
- Especifica valores para los siguientes parámetros de entrada:
- Delimitador de división (opcional): Déjalo vacío. Cada solicitud de webhook contiene un solo evento de identificación.
- Espacio de nombres del recurso: Es el espacio de nombres del recurso.
- Etiquetas de transferencia: Es la etiqueta que se aplicará a los eventos de este feed.
- Haz clic en Siguiente.
- Revisa la nueva configuración del feed en la pantalla Finalizar y, luego, haz clic en Enviar.
Genera y guarda la clave secreta
Después de crear el feed, debes generar una clave secreta para la autenticación:
- En la página de detalles del feed, haz clic en Generar clave secreta.
- Un diálogo muestra la clave secreta.
- Copia y guarda la clave secreta de forma segura.
Importante: La clave secreta solo se muestra una vez y no se puede recuperar más adelante. Si la pierdes, deberás generar una nueva.
Obtén la URL del extremo del feed
- Ve a la pestaña Detalles del feed.
- En la sección Endpoint Information, copia la URL del extremo del feed.
El formato de la URL es el siguiente:
https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreateo
https://<REGION>-malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreateGuarda esta URL para los próximos pasos.
Haz clic en Listo.
Crea una clave de API de Google Cloud
Chronicle requiere una clave de API para la autenticación. Crea una clave de API restringida en la Google Cloud Console.
Crea la clave de API
- Ve a la página Credenciales de la consola de Google Cloud.
- Selecciona tu proyecto (el proyecto asociado con tu instancia de Chronicle).
- Haz clic en Crear credenciales > Clave de API.
- Se creará una clave de API y se mostrará en un diálogo.
- Haz clic en Editar clave de API para restringir la clave.
Restringe la clave de API
- En la página de configuración de la clave de API, haz lo siguiente:
- Nombre: Ingresa un nombre descriptivo (por ejemplo,
Chronicle FingerprintJS Webhook API Key).
- Nombre: Ingresa un nombre descriptivo (por ejemplo,
- En Restricciones de API, haz lo siguiente:
- Selecciona Restringir clave.
- En el menú desplegable Seleccionar APIs, busca y selecciona Google SecOps API (o Chronicle API).
- Haz clic en Guardar.
- Copia el valor de la clave de API del campo Clave de API en la parte superior de la página.
Guarda la clave de API de forma segura.
Configura el webhook de FingerprintJS
Construye la URL del webhook
Combina la URL del extremo de Chronicle y la clave de API:
<ENDPOINT_URL>?key=<API_KEY>Ejemplo:
https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate?key=AIzaSyD...
Crea un webhook en el panel de FingerprintJS
- Accede al panel de FingerprintJS.
- Ve a Panel > Webhooks.
- Haz clic en Add webhook (Agregar webhook).
- Proporciona los siguientes detalles de configuración:
- URL: Pega la URL completa del extremo con la clave de API que se indicó anteriormente.
- Entorno (opcional): Si seleccionas un entorno, tu webhook solo generará informes sobre los eventos de un entorno coincidente. Déjalo vacío para recibir eventos de todos los entornos.
- Autenticación básica (opcional): Expande Autenticación básica si deseas agregar autenticación adicional. Para la integración de Chronicle, puedes dejar este campo vacío, ya que la autenticación se controla a través de la clave de API y la clave secreta.
- Haz clic en Crear webhook.
- Se mostrará un modal de éxito con el mensaje Webhooks created.
- Importante: Si usas firmas de webhook (solo para el plan Enterprise), copia y guarda la clave de encriptación que se muestra en la ventana modal de confirmación. La clave se muestra solo una vez.
Agrega la clave secreta de Chronicle al webhook
FingerprintJS no admite encabezados HTTP personalizados durante la creación de webhooks. Debes agregar la clave secreta de Chronicle como parámetro de consulta en la URL del webhook.
Actualiza la URL del webhook para incluir la clave secreta:
<ENDPOINT_URL>?key=<API_KEY>&secret=<SECRET_KEY>Ejemplo:
https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate?key=AIzaSyD...&secret=abcd1234...
Para actualizar la URL del webhook, sigue estos pasos:
- En el panel de FingerprintJS, ve a Panel > Webhooks.
- Busca tu webhook en la tabla y haz clic en el ícono de Editar.
- Actualiza el campo URL con la URL completa, que incluye la clave de API y la clave secreta.
- Haz clic en Editar webhook.
Prueba el webhook
- En el panel de FingerprintJS, ve a Panel > Webhooks.
- Busca tu webhook en la tabla.
- Haz clic en Enviar evento de prueba.
- Espera la confirmación de que el evento de prueba se envió correctamente.
Verifica que el webhook muestre un estado de entrega exitosa.
Referencia de métodos de autenticación
Los feeds de webhook de Chronicle admiten varios métodos de autenticación. Los webhooks de FingerprintJS usan parámetros de consulta para la autenticación.
Método de parámetros de consulta
FingerprintJS no admite encabezados HTTP personalizados durante la creación de webhooks, por lo que las credenciales deben agregarse a la URL.
Formato de URL:
<ENDPOINT_URL>?key=<API_KEY>&secret=<SECRET_KEY>Ejemplo:
https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate?key=AIzaSyD...&secret=abcd1234...
Formato de la solicitud:
POST <ENDPOINT_URL>?key=<API_KEY>&secret=<SECRET_KEY> HTTP/1.1 Content-Type: application/json { "visitorId": "3HNey93AkBW6CRbxV6xP", "requestId": "1708102555327.NLOjmg", "timestamp": 1582299576512 }
Tabla de asignación de UDM
| Campo de registro | Asignación de UDM | Lógica |
|---|---|---|
| rawDeviceAttributes.architecture.value, rawDeviceAttributes.audio.value, rawDeviceAttributes.colorDepth.value, rawDeviceAttributes.colorGamut.value, rawDeviceAttributes.contrast.value, rawDeviceAttributes.cookiesEnabled.value, rawDeviceAttributes.deviceMemory.value, rawDeviceAttributes.fonts.value, rawDeviceAttributes.forcedColors.value, rawDeviceAttributes.hardwareConcurrency.value, rawDeviceAttributes.hdr.value, rawDeviceAttributes.indexedDB.value, rawDeviceAttributes.localStorage.value, rawDeviceAttributes.math.value, rawDeviceAttributes.monochrome.value, rawDeviceAttributes.openDatabase.value, rawDeviceAttributes.pdfViewerEnabled.value, rawDeviceAttributes.reducedMotion.value, rawDeviceAttributes.screenFrame.value, rawDeviceAttributes.screenResolution.value, rawDeviceAttributes.sessionStorage.value, rawDeviceAttributes.touchSupport.value.maxTouchPoints, rawDeviceAttributes.languages.value, rawDeviceAttributes.vendorFlavors.value, rawDeviceAttributes.fontPreferences.value.apple, rawDeviceAttributes.fontPreferences.value.default, rawDeviceAttributes.fontPreferences.value.min, rawDeviceAttributes.fontPreferences.value.mono, rawDeviceAttributes.fontPreferences.value.sans, rawDeviceAttributes.fontPreferences.value.serif, rawDeviceAttributes.fontPreferences.value.system | additional.fields | Se combinaron etiquetas creadas a partir de campos de origen |
| has_principal, has_target, has_target_resource | metadata.event_type | Se establece en "NETWORK_CONNECTION" si has_principal y has_target son verdaderos; de lo contrario, se establece en "USER_RESOURCE_ACCESS" si has_target_resource es verdadero, en "STATUS_UPDATE" si has_principal es verdadero o en "GENERIC_EVENT" |
| source_type | metadata.product_event_type | Valor copiado directamente |
| requestId | metadata.product_log_id | Valor copiado directamente |
| browserDetails.userAgent | network.http.parsed_user_agent | Se analizó a partir de browserDetails.userAgent |
| browserDetails.browserName | network.http.parsed_user_agent.browser | Valor copiado directamente |
| browserDetails.browserFullVersion | network.http.parsed_user_agent.browser_version | Valor copiado directamente |
| browserDetails.device | network.http.parsed_user_agent.device | Valor copiado directamente |
| network.http.parsed_user_agent.family | Se establece en "USER_DEFINED". | |
| browserDetails.os | network.http.parsed_user_agent.os | Valor copiado directamente |
| browserDetails.clientReferrer | network.http.referral_url | Valor copiado directamente |
| browserDetails.userAgent, userAgent | network.http.user_agent | Valor de userAgent si no está vacío; de lo contrario, browserDetails.userAgent |
| tag.session | network.session_id | Valor copiado directamente |
| rawDeviceAttributes.vendor.value | principal.administrative_domain | Valor copiado directamente |
| ip | principal.asset.ip | Valor copiado directamente |
| ip | principal.ip | Valor copiado directamente |
| ipInfo.v4.geolocation.city.name | principal.location.city | Valor copiado directamente |
| ipInfo.v4.geolocation.country.name | principal.location.country_or_region | Valor copiado directamente |
| ipInfo.v4.geolocation.latitude | principal.location.region_coordinates.latitude | Se convirtió en un número de punto flotante |
| ipInfo.v4.geolocation.longitude | principal.location.region_coordinates.longitude | Se convirtió en un número de punto flotante |
| browserDetails.osVersion, rawDeviceAttributes.platform.value | principal.platform_version | Valor de rawDeviceAttributes.platform.value si no está vacío; de lo contrario, browserDetails.osVersion |
| ipInfo.v4.asn.asn, ipInfo.v4.asn.network, ipInfo.v4.asn.name, ipInfo.v4.geolocation.accuracyRadius, ipInfo.v4.geolocation.continent.name, ipInfo.v4.geolocation.timezone, ipInfo.v4.geolocation.subdivisions.isoCode, ipInfo.v4.geolocation.subdivisions.name | principal.resource.attribute.labels | Se combinaron etiquetas creadas a partir de campos de origen |
| bot.result, browserDetails.browserMajorVersion, confidence.score, confidence.revision, developerTools.result, highActivity.result, incognito, ipBlocklist.result, ipBlocklist.details.attackSource, ipBlocklist.details.emailSpam, visitorFound, visitorId, tag.request, privacySettings.result, proxy.result, suspectScore.result, tor.result, virtualMachine.result, tampering.anomalyScore, tampering.antiDetectBrowser, tampering.result, vpn.confidence, vpn.originCountry, vpn.originTimezone, vpn.result, vpn.methods.auxiliaryMobile, vpn.methods.osMismatch, vpn.methods.publicVPN, vpn.methods.timezoneMismatch, velocity.distinctCountry.intervals.1h, velocity.distinctCountry.intervals.24h, velocity.distinctCountry.intervals.5m, velocity.distinctIp.intervals.1h, velocity.distinctIp.intervals.24h, velocity.distinctIp.intervals.5m, velocity.events.intervals.1h, velocity.events.intervals.24h, velocity.events.intervals.5m, velocity.ipEvents.intervals.1h, velocity.ipEvents.intervals.24h, velocity.ipEvents.intervals.5m, rawDeviceAttributes.webGlBasics.value.renderer, rawDeviceAttributes.webGlBasics.value.rendererUnmasked, rawDeviceAttributes.webGlBasics.value.vendorUnmasked, rawDeviceAttributes.webGlBasics.value.shadingLanguageVersion, rawDeviceAttributes.webGlExtensions.value.contextAttributes, rawDeviceAttributes.webGlExtensions.value.extensions, rawDeviceAttributes.webGlExtensions.value.extensionParameters, rawDeviceAttributes.webGlExtensions.value.parameters, rawDeviceAttributes.webGlExtensions.value.shaderPrecisions, rawDeviceAttributes.mathML.value.bottom, rawDeviceAttributes.mathML.value.top, rawDeviceAttributes.mathML.value.left, rawDeviceAttributes.mathML.value.right, rawDeviceAttributes.mathML.value.width, rawDeviceAttributes.mathML.value.height, rawDeviceAttributes.mathML.value.font, rawDeviceAttributes.mathML.value.x, rawDeviceAttributes.mathML.value.y, rawDeviceAttributes.emoji.value.bottom, rawDeviceAttributes.emoji.value.top, rawDeviceAttributes.emoji.value.left, rawDeviceAttributes.emoji.value.right, rawDeviceAttributes.emoji.value.width, rawDeviceAttributes.emoji.value.height, rawDeviceAttributes.emoji.value.font, rawDeviceAttributes.emoji.value.x, rawDeviceAttributes.emoji.value.y, rawDeviceAttributes.canvas.value.Geometry, rawDeviceAttributes.canvas.value.Text, rawDeviceAttributes.canvas.value.Winding | security_result.detection_fields | Se combinaron etiquetas creadas a partir de campos de origen |
| rawDeviceAttributes.webGlBasics.value.vendor | target.administrative_domain | Valor copiado directamente |
| ipInfo.v6.address | target.asset.ip | Valor copiado directamente |
| ipInfo.v6.address | target.ip | Valor copiado directamente |
| ipInfo.v6.geolocation.city.name | target.location.city | Valor copiado directamente |
| ipInfo.v6.geolocation.country.name | target.location.country_or_region | Valor copiado directamente |
| ipInfo.v6.geolocation.latitude | target.location.region_coordinates.latitude | Se convirtió en un número de punto flotante |
| ipInfo.v6.geolocation.longitude | target.location.region_coordinates.longitude | Se convirtió en un número de punto flotante |
| ruta de acceso | target.path | Valor copiado directamente |
| rawDeviceAttributes.webGlBasics.value.version | target.platform_version | Valor copiado directamente |
| ipInfo.v6.asn.asn, ipInfo.v6.asn.network, ipInfo.v6.asn.name, ipInfo.v6.geolocation.accuracyRadius, ipInfo.v6.geolocation.continent.name, ipInfo.v6.geolocation.timezone, ipInfo.v6.geolocation.subdivisions.isoCode, ipInfo.v6.geolocation.subdivisions.name | target.resource.attribute.labels | Se combinaron etiquetas creadas a partir de campos de origen |
| url | target.url | Valor copiado directamente |
| metadata.product_name | Se establece en "FINGERPRINT_JS". | |
| metadata.vendor_name | Se establece en "FINGERPRINT_JS". |
Registro de cambios
Consulta el registro de cambios de este analizador
¿Necesitas más ayuda? Obtén respuestas de miembros de la comunidad y profesionales de Google SecOps.