Recopila registros de HackerOne
En este documento, se explica cómo configurar HackerOne para enviar registros a las Operaciones de seguridad de Google con webhooks.
HackerOne es una plataforma de coordinación de vulnerabilidades y recompensas por errores que conecta a las organizaciones con investigadores de seguridad para identificar y corregir vulnerabilidades de seguridad. La plataforma ofrece programas de recompensas por detección de errores, programas de divulgación de vulnerabilidades, pruebas de penetración y pruebas de seguridad continuas durante todo el ciclo de vida del desarrollo de software.
Antes de comenzar
Asegúrate de cumplir con los siguientes requisitos previos:
- Una instancia de Google SecOps
- Programa de HackerOne con nivel Profesional o Enterprise (los webhooks solo están disponibles para estos niveles)
- Acceso de administrador a la configuración de tu programa de HackerOne
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,
HackerOne Vulnerability Reports). - Selecciona Webhook como el Tipo de origen.
- Selecciona HackerOne 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 JSON.
- Espacio de nombres del recurso: Es el espacio de nombres del recurso.
- Etiquetas de transmisión: 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.
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 clave de API, haz lo siguiente:
- Nombre: Ingresa un nombre descriptivo (por ejemplo,
Chronicle HackerOne Webhook API Key).
- Nombre: Ingresa un nombre descriptivo (por ejemplo,
- En Restricciones de API, haz lo siguiente:
- Selecciona Restringir clave.
- En la lista Select 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 HackerOne
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 HackerOne
- Accede a HackerOne y navega a tu programa.
- Ve a Participaciones, haz clic en el menú de tres puntos del programa que deseas configurar y, luego, en Configuración.
- Ve a Automatización > Webhooks.
- Haz clic en Webhook nuevo.
- Proporciona los siguientes detalles de configuración:
- URL de carga útil: Pega la URL completa del extremo con la clave de API que se indicó anteriormente.
- Secreto: Pega la clave secreta de la creación del feed de Chronicle.
- Selecciona los eventos que deseas que activen el webhook: Elige una de las siguientes opciones:
- Envíame todo: Todos los eventos activarán el webhook.
- Permítanme especificar eventos individuales: Selecciona los eventos específicos que deseas enviar a Chronicle. Eventos recomendados para la supervisión de la seguridad:
- report_created: Cuando un hacker envía un nuevo informe de vulnerabilidad
- report_triaged: Cuando se prioriza un informe
- report_resolved: Cuando se resuelve un informe
- report_bounty_awarded: Cuando se otorga una recompensa
- report_swag_awarded: Cuando se otorga merchandising
- program_hacker_joined: Cuando un hacker se une al programa
- program_hacker_left: Cuando un hacker abandona el programa
- Haz clic en Add webhook (Agregar webhook).
Prueba el webhook
- En la página de configuración del webhook, selecciona Solicitud de prueba para enviar una solicitud de ejemplo a la URL de carga útil configurada.
- Verifica que la respuesta sea HTTP 200.
- Verifica el feed de Chronicle para ver el evento de prueba en un plazo de 1 a 2 minutos.
Verifica que el webhook funcione
Verifica el estado del webhook de HackerOne
- Accede a la consola de HackerOne.
- Ve a Participación, haz clic en el menú de tres puntos de tu programa y, luego, en Configuración.
- Ve a Automatización > Webhooks.
- Haz clic en tu webhook para ver los detalles.
- En la sección Recent deliveries, verifica que las entregas recientes muestren el estado correcto (HTTP 200).
- Haz clic en cualquier entrega para ver la solicitud de carga útil de POST.
Verifica el estado del feed de Chronicle
- Ve a Configuración de SIEM > Feeds en Chronicle.
- Busca tu feed de webhook de HackerOne.
- Verifica la columna Estado (debe ser Activo).
- Verifica el recuento de Eventos recibidos (debe aumentar).
- Verifica la marca de tiempo de Last succeeded on (debe ser reciente).
Verifica los registros en Chronicle
- Ve a Búsqueda > Búsqueda de UDM.
Usa la siguiente consulta:
metadata.vendor_name = "HACKERONE" AND metadata.product_name = "HACKERONE"Ajusta el intervalo de tiempo a la última hora.
Verifica que los eventos aparezcan en los resultados.
Referencia de métodos de autenticación
Los feeds de webhook de Chronicle admiten varios métodos de autenticación. Los webhooks de HackerOne usan una combinación de parámetros de consulta y validación de firmas.
Método 1: Parámetros de consulta con validación de firma (recomendado para HackerOne)
HackerOne envía webhooks a la URL de carga útil configurada. La autenticación se controla a través de los siguientes métodos:
- Clave de API en la URL: La clave de API de Chronicle se agrega como un parámetro de consulta a la URL de carga útil.
Validación de firma secreta: HackerOne genera un encabezado X-H1-Signature que contiene un resumen hexadecimal HMAC SHA256 del cuerpo de la solicitud firmado con el secreto configurado.
Formato de URL:
<ENDPOINT_URL>?key=<API_KEY>Formato de la solicitud:
POST <ENDPOINT_URL>?key=<API_KEY> HTTP/1.1 Content-Type: application/json X-H1-Signature: sha256=<HMAC_HEXDIGEST> X-H1-Event: <EVENT_TYPE> X-H1-Delivery: <DELIVERY_ID> { "data": { "activity": {...}, "report": {...} } }
Ventajas:
- Autenticación doble: Clave de API para el acceso a Chronicle y firma para la validación de la carga útil
- HackerOne proporciona la generación de firmas integrada
- Verificación de integridad de la carga útil segura
Validación de la firma
HackerOne incluye los siguientes encabezados con cada solicitud de webhook:
- X-H1-Signature: Resumen hexadecimal de HMAC SHA256 del cuerpo de la solicitud (formato:
sha256=<hexdigest>) - X-H1-Event: Es el tipo de evento que activó el webhook.
- X-H1-Delivery: Es el identificador único de la entrega.
- X-H1-Signature: Resumen hexadecimal de HMAC SHA256 del cuerpo de la solicitud (formato:
Para validar la firma en tu extremo receptor, haz lo siguiente:
import hmac import hashlib def validate_request(request_body, secret, signature): _, digest = signature.split('=') generated_digest = hmac.new( secret.encode(), request_body.encode(), hashlib.sha256 ).hexdigest() return hmac.compare_digest(digest, generated_digest)
Tipos de eventos de webhook
HackerOne admite los siguientes tipos de eventos de webhook:
| Tipo de evento | Descripción |
|---|---|
| report_created | Se activa cuando un hacker envía un informe de vulnerabilidad nuevo |
| report_triaged | Se activa cuando se clasifica un informe. |
| report_resolved | Se activa cuando se resuelve un informe |
| report_bounty_awarded | Se activa cuando se otorga una recompensa por un informe. |
| report_swag_awarded | Se activa cuando se otorgan artículos promocionales por un informe. |
| report_became_public | Se activa cuando un informe se vuelve público |
| program_hacker_joined | Se activa cuando un hacker se une al programa |
| program_hacker_left | Se activa cuando un hacker abandona el programa |
Tabla de asignación de UDM
| Campo de registro | Asignación de UDM | Lógica |
|---|---|---|
| attributes.cleared, attributes.rules_of_engagement_signed, attributes.identity_verified, attributes.background_checked, attributes.citizenship_verified, attributes.residency_verified, type, attributes.title, attributes.main_state, attributes.state, relationships.reporter.data.type, relationships.reporter.data.attributes.reputation, relationships.reporter.data.attributes.signal, relationships.reporter.data.attributes.impact, relationships.reporter.data.attributes.disabled, relationships.reporter.data.attributes.profile_picture.62x62, relationships.reporter.data.attributes.profile_picture.82x82, relationships.reporter.data.attributes.profile_picture.110x110, relationships.reporter.data.attributes.profile_picture.260x260, relationships.reporter.data.attributes.hackerone_triager, relationships.program.data.id, relationships.program.data.type, relationships.program.data.attributes.handle, relationships.severity.data.type, relationships.severity.data.attributes.rating, relationships.severity.data.attributes.author_type, relationships.severity.data.attributes.calculation_method, relationships.weakness.data.id, relationships.weakness.data.type, relationships.weakness.data.attributes.name, relationships.weakness.data.attributes.description, relationships.weakness.data.attributes.external_id, relationships.structured_scope.data.id, relationships.structured_scope.data.type, relationships.structured_scope.data.attributes.asset_type, relationships.structured_scope.data.attributes.eligible_for_bounty, relationships.structured_scope.data.attributes.eligible_for_submission, relationships.structured_scope.data.attributes.instruction, relationships.structured_scope.data.attributes.max_severity, relationships.structured_scope.data.attributes.confidentiality_requirement, relationships.structured_scope.data.attributes.integrity_requirement, relationships.structured_scope.data.attributes.availability_requirement, relationships.inboxes.data.id, relationships.inboxes.data.type, relationships.inboxes.data.attributes.name, relationships.inboxes.data.attributes.type | additional.fields | Se combinan como etiquetas de pares clave-valor |
| timestamp | metadata.event_timestamp | Se analizó con el filtro de fecha con el formato aaaa-MM-dd'T'HH:mm:ss.SSSZ. |
| metadata.event_type | Se establece en "STATUS_UPDATE" si has_principal es verdadero, en "USER_UNCATEGORIZED" si has_principal_user_user es verdadero y, de lo contrario, en "GENERIC_EVENT". | |
| id | metadata.product_log_id | Valor copiado directamente |
| relationships.structured_scope.data.attributes.asset_identifier | principal.asset.asset_id | Tiene el prefijo "ASSET:". |
| attributes.email_alias | principal.user.email_addresses | Combinado |
| relationships.reporter.data.id | principal.user.employee_id | Valor copiado directamente |
| relationships.reporter.data.attributes.name | principal.user.first_name | Valor copiado directamente |
| attributes.username, relationships.reporter.data.attributes.username | principal.user.user_display_name | Valor de relationships.reporter.data.attributes.username si no está vacío; de lo contrario, attributes.username |
| relationships.severity.data.attributes.user_id | principal.user.userid | Valor copiado directamente |
| relationships.severity.data.id | security_result.rule_id | Valor copiado directamente |
| relationships.severity.data.attributes.max_severity | security_result.severity | Se convirtió a mayúsculas |
| attributes.vulnerability_information | security_result.summary | Valor copiado directamente |
¿Necesitas más ayuda? Obtén respuestas de miembros de la comunidad y profesionales de Google SecOps.