Coletar registros de impressão digital
Versão do analisador:1.0
Este documento explica como configurar o Fingerprint (antigo FingerprintJS) para enviar registros ao Google Security Operations usando webhooks.
O Fingerprint é uma plataforma de inteligência de dispositivos que oferece recursos de identificação de visitantes e detecção de fraudes. Ele gera identificadores exclusivos de visitantes e fornece indicadores inteligentes, incluindo detecção de bots, VPN e modo incógnito, além de outros insights de inteligência de dispositivos. Quando um visitante é identificado pelo agente JavaScript do FingerprintJS, os webhooks podem enviar os dados de eventos de identificação para o Google Security Operations em tempo real.
Antes de começar
Verifique se você atende os seguintes pré-requisitos:
- Uma instância do Google SecOps
- Conta do FingerprintJS com suporte a webhook
- Acesso ao console do Google Cloud (para criação de chaves de API)
- Agente JavaScript FingerprintJS instalado no seu site ou aplicativo
Criar um feed de webhook no Google SecOps
Criar o feed
- Acesse Configurações do SIEM > Feeds.
- Clique em Adicionar novo feed.
- Na próxima página, clique em Configurar um único feed.
- No campo Nome do feed, insira um nome para o feed (por exemplo,
FingerprintJS Identification Events). - Selecione Webhook como o Tipo de origem.
- Selecione FingerprintJS como o Tipo de registro.
- Clique em Próxima.
- Especifique valores para os seguintes parâmetros de entrada:
- Delimitador de divisão (opcional): deixe em branco. Cada solicitação de webhook contém um único evento de identificação.
- Namespace do recurso: o namespace do recurso.
- Rótulos de ingestão: o rótulo a ser aplicado aos eventos deste feed.
- Clique em Próxima.
- Revise a nova configuração do feed na tela Finalizar e clique em Enviar.
Gerar e salvar a chave secreta
Depois de criar o feed, gere uma chave secreta para autenticação:
- Na página de detalhes do feed, clique em Gerar chave secreta.
- Uma caixa de diálogo mostra a chave secreta.
- Copie e salve a chave secreta com segurança.
Importante: a chave secreta é exibida apenas uma vez e não pode ser recuperada depois. Se você perder a chave, será necessário gerar outra.
Receber o URL do endpoint do feed
- Acesse a guia Detalhes do feed.
- Na seção Informações do endpoint, copie o URL do endpoint do feed.
O formato do URL é:
https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreateou
https://<REGION>-malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreateSalve esse URL para as próximas etapas.
Clique em Concluído.
Criar chave de API do Google Cloud
O Chronicle exige uma chave de API para autenticação. Crie uma chave de API restrita no console do Google Cloud.
Criar a chave de API
- Acesse a página "Credenciais" do console do Google Cloud.
- Selecione seu projeto (o projeto associado à sua instância do Chronicle).
- Clique em Criar credenciais > Chave de API.
- Uma chave de API é criada e mostrada em uma caixa de diálogo.
- Clique em Editar chave de API para restringir a chave.
Restringir a chave de API
- Na página de configurações da chave de API:
- Nome: insira um nome descritivo, por exemplo,
Chronicle FingerprintJS Webhook API Key.
- Nome: insira um nome descritivo, por exemplo,
- Em Restrições de API:
- Selecione Restringir chave.
- No menu suspenso Selecionar APIs, pesquise e selecione API Google SecOps (ou API Chronicle).
- Clique em Salvar.
- Copie o valor da chave de API do campo Chave de API na parte de cima da página.
Salve a chave de API com segurança.
Configurar o webhook do FingerprintJS
Criar o URL do webhook
Combine o URL do endpoint do Chronicle e a chave de API:
<ENDPOINT_URL>?key=<API_KEY>Exemplo:
https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate?key=AIzaSyD...
Criar webhook no painel do FingerprintJS
- Faça login no painel do FingerprintJS.
- Acesse Painel > Webhooks.
- Clique em Add webhook.
- Informe os seguintes detalhes de configuração:
- URL: cole o URL completo do endpoint com a chave de API acima.
- Ambiente (opcional): se você selecionar um ambiente, o webhook vai gerar relatórios apenas sobre eventos de um ambiente correspondente. Deixe em branco para receber eventos de todos os ambientes.
- Autenticação básica (opcional): expanda Autenticação básica se quiser adicionar mais autenticação. Para a integração do Chronicle, deixe esse campo vazio, já que a autenticação é processada pela chave de API e pela chave secreta.
- Clique em Criar webhook.
- Um modal de sucesso mostra Webhooks criados.
- Importante: se você estiver usando assinaturas de webhook (somente no plano Enterprise), copie e salve a chave de criptografia mostrada no modal de sucesso. A chave é mostrada apenas uma vez.
Adicionar a chave secreta do Chronicle ao webhook
O FingerprintJS não é compatível com cabeçalhos HTTP personalizados durante a criação de webhooks. É preciso adicionar a chave secreta do Chronicle como um parâmetro de consulta no URL do webhook.
Atualize o URL do webhook para incluir a chave secreta:
<ENDPOINT_URL>?key=<API_KEY>&secret=<SECRET_KEY>Exemplo:
https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate?key=AIzaSyD...&secret=abcd1234...
Para atualizar o URL do webhook:
- No painel do FingerprintJS, acesse Painel > Webhooks.
- Encontre o webhook na tabela e clique no ícone Editar.
- Atualize o campo URL com o URL completo, incluindo a chave de API e a chave secreta.
- Clique em Editar webhook.
Testar o webhook
- No painel do FingerprintJS, acesse Painel > Webhooks.
- Encontre seu webhook na tabela.
- Clique em Enviar evento de teste.
- Aguarde a confirmação de que o evento de teste foi enviado.
Verifique se o webhook mostra um status de entrega bem-sucedido.
Referência de métodos de autenticação
Os feeds de webhook do Chronicle são compatíveis com vários métodos de autenticação. Os webhooks do FingerprintJS usam parâmetros de consulta para autenticação.
Método de parâmetros de consulta
O FingerprintJS não é compatível com cabeçalhos HTTP personalizados durante a criação de webhooks. Portanto, as credenciais precisam ser anexadas ao URL.
Formato do URL:
<ENDPOINT_URL>?key=<API_KEY>&secret=<SECRET_KEY>Exemplo:
https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate?key=AIzaSyD...&secret=abcd1234...
Formato da solicitação:
POST <ENDPOINT_URL>?key=<API_KEY>&secret=<SECRET_KEY> HTTP/1.1 Content-Type: application/json { "visitorId": "3HNey93AkBW6CRbxV6xP", "requestId": "1708102555327.NLOjmg", "timestamp": 1582299576512 }
Tabela de mapeamento de UDM
| Campo de registro | Mapeamento do 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 | Mesclado de rótulos criados com base em campos de origem |
| has_principal, has_target, has_target_resource | metadata.event_type | Definido como "NETWORK_CONNECTION" se has_principal e has_target forem verdadeiros. Caso contrário, "USER_RESOURCE_ACCESS" se has_target_resource for verdadeiro. Caso contrário, "STATUS_UPDATE" se has_principal for verdadeiro. Caso contrário, "GENERIC_EVENT". |
| source_type | metadata.product_event_type | Valor copiado diretamente |
| requestId | metadata.product_log_id | Valor copiado diretamente |
| browserDetails.userAgent | network.http.parsed_user_agent | Analisado de browserDetails.userAgent |
| browserDetails.browserName | network.http.parsed_user_agent.browser | Valor copiado diretamente |
| browserDetails.browserFullVersion | network.http.parsed_user_agent.browser_version | Valor copiado diretamente |
| browserDetails.device | network.http.parsed_user_agent.device | Valor copiado diretamente |
| network.http.parsed_user_agent.family | Definido como "USER_DEFINED" | |
| browserDetails.os | network.http.parsed_user_agent.os | Valor copiado diretamente |
| browserDetails.clientReferrer | network.http.referral_url | Valor copiado diretamente |
| browserDetails.userAgent, userAgent | network.http.user_agent | Valor de userAgent se não estiver vazio. Caso contrário, browserDetails.userAgent. |
| tag.session | network.session_id | Valor copiado diretamente |
| rawDeviceAttributes.vendor.value | principal.administrative_domain | Valor copiado diretamente |
| ip | principal.asset.ip | Valor copiado diretamente |
| ip | principal.ip | Valor copiado diretamente |
| ipInfo.v4.geolocation.city.name | principal.location.city | Valor copiado diretamente |
| ipInfo.v4.geolocation.country.name | principal.location.country_or_region | Valor copiado diretamente |
| ipInfo.v4.geolocation.latitude | principal.location.region_coordinates.latitude | Convertido para ponto flutuante |
| ipInfo.v4.geolocation.longitude | principal.location.region_coordinates.longitude | Convertido para ponto flutuante |
| browserDetails.osVersion, rawDeviceAttributes.platform.value | principal.platform_version | Valor de rawDeviceAttributes.platform.value se não estiver vazio. Caso contrário, 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 | Mesclado de rótulos criados com base em campos de origem |
| 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 | Mesclado de rótulos criados com base em campos de origem |
| rawDeviceAttributes.webGlBasics.value.vendor | target.administrative_domain | Valor copiado diretamente |
| ipInfo.v6.address | target.asset.ip | Valor copiado diretamente |
| ipInfo.v6.address | target.ip | Valor copiado diretamente |
| ipInfo.v6.geolocation.city.name | target.location.city | Valor copiado diretamente |
| ipInfo.v6.geolocation.country.name | target.location.country_or_region | Valor copiado diretamente |
| ipInfo.v6.geolocation.latitude | target.location.region_coordinates.latitude | Convertido para ponto flutuante |
| ipInfo.v6.geolocation.longitude | target.location.region_coordinates.longitude | Convertido para ponto flutuante |
| path | target.path | Valor copiado diretamente |
| rawDeviceAttributes.webGlBasics.value.version | target.platform_version | Valor copiado diretamente |
| 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 | Mesclado de rótulos criados com base em campos de origem |
| url | target.url | Valor copiado diretamente |
| metadata.product_name | Definido como "FINGERPRINT_JS" | |
| metadata.vendor_name | Definido como "FINGERPRINT_JS" |
Registro de alterações
Ver o registro de alterações deste analisador
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.