Ir al contenido principal

Axur Credentials Feed - ServiceNow

Cómo crear un incidente en ServiceNow por cada credencial expuesta detectada por la Plataforma Axur, usando un Credentials Feed (Push o Pull).

Descripción general

Un Credentials Feed entrega las credenciales expuestas (inicios de sesión filtrados de empleados o clientes) que detecta la Plataforma Axur. Un pequeño script en ServiceNow convierte cada credencial en un registro de Incidente, para que su equipo pueda restablecer la contraseña y dar seguimiento a la respuesta.

Figura 1: Los dos modos de entrega. Ambos usan el mismo JSON y el mismo script de mapeo.

  • Push (Webhook 2.0): casi en tiempo real

    • La Plataforma Axur envía las credenciales a un endpoint que usted crea en ServiceNow. Su instancia debe aceptar llamadas entrantes.

  • Pull (polling): más fácil de aprobar

    • ServiceNow consulta el feed cada X minutos. El tráfico es solo saliente, y la latencia es igual al intervalo de la programación.

¿Ya usa la guía del Tickets Feed?

Esta guía sigue la misma estructura, con sus propios nombres de script (AxurCredentialFeedMapper, axur.credentials_feed.url). Ambas integraciones pueden funcionar en paralelo en la misma instancia y pueden compartir la misma propiedad de API Key.

Requisitos previos

  • Una instancia de ServiceNow y un usuario admin (o web_service_admin para Push). Para probar primero, use una Personal Developer Instance (PDI) gratuita de developer.servicenow.com. Su URL tiene el formato https://dev123456.service-now.com.

  • Un usuario con perfil manager en la Plataforma Axur para crear el feed.

  • Una API Key de la Plataforma Axur (solo Pull). Consulte el paso Obtener la API Key.

UI clásica vs. Next Experience

Los menús de ServiceNow se ven diferentes en la interfaz clásica (UI16) y en Next Experience (menú All). Algunos atajos, como escribir sys_properties.list en el filtro, no funcionan en todas las versiones. Cada paso a continuación también incluye una URL directa que funciona en ambas interfaces. Reemplace <instance> por el nombre de su instancia, por ejemplo dev123456.

URLs directas usadas en esta guía

Qué

URL directa

Nueva propiedad del sistema

https://<instance>.service-now.com/sys_properties.do?sys_id=-1

Lista de propiedades del sistema

https://<instance>.service-now.com/sys_properties_list.do

Nuevo Script Include

https://<instance>.service-now.com/sys_script_include.do?sys_id=-1

Nueva Scheduled Script Execution

https://<instance>.service-now.com/sysauto_script.do?sys_id=-1

Nueva Scripted REST API

https://<instance>.service-now.com/sys_ws_definition.do?sys_id=-1

Incidentes creados por el feed

https://<instance>.service-now.com/incident_list.do?sysparm_query=correlation_idISNOTEMPTY

Logs del sistema

https://<instance>.service-now.com/syslog_list.do


Obtener el feed y la API Key en la Plataforma Axur

Haga este paso primero. Pull necesita la URL del feed y la API Key antes de crear cualquier cosa en ServiceNow.

Crear el feed

  1. Vaya a one.axur.com/api-integrations → sección Feeds → Add feed. Puede elegir la plantilla Employee credentials o User credentials, o hacer clic en Skip templates.

  2. Elija el tipo Credentials.

  3. Elija el modo de entrega: Pull o Push. Para Push, ingrese la URL del endpoint que creará en el paso 6.

  4. El campo Event date viene precargado con la fecha de creación (created). Cada credencial llega una sola vez, cuando la Plataforma Axur la detecta por primera vez.

  5. En Feed parameters, elija qué credenciales recibir. Combine filtros con &:

  6. Recomendado: agregue también el parámetro fields que se muestra abajo. Así el feed devuelve solo lo que usa el script, y las contraseñas nunca salen de la Plataforma Axur:

    fields=id,created,detectionDate,customer,assets,status,credential.types,user,user.type,access.url,source.name

    Ejemplo combinado con un filtro: credential.types=employee&fields=id,created,…

  7. Defina un título, por ejemplo “ServiceNow – Credenciales expuestas”, y guarde.

  8. Copie la URL del feed que aparece para el feed en la lista. Tiene el formato https://api.axur.com/gateway/1.0/api/integration-feed/feeds/feed/<ID>.

    Figura 2: Configuración sugerida del feed (ilustración; la pantalla real puede verse diferente).

Obtener la API Key (solo Pull)

  1. En la Plataforma Axur, abra My Preferences → pestaña API KEY.

  2. Cree una nueva clave y cópiela de inmediato. Guárdela en un gestor de contraseñas hasta crear la propiedad en ServiceNow en el paso Guardar la URL y la API Key.

La clave pertenece al usuario que la creó

La clave solo ve lo que ese usuario puede ver en la Plataforma Axur. Si el usuario se desactiva, se bloquea o se elimina, la clave se revoca y el job empieza a fallar con 401 Unauthorized. Cree la clave con un usuario que tenga acceso a las credenciales y que no vaya a ser desactivado, como un usuario de integración dedicado. Nunca comparta la clave ni la escriba en scripts.


Mapeo de campos

Cada elemento de collectionData.detections[] se convierte en un registro de la tabla Incident. Los colores indican de dónde proviene cada dato:

Tabla de mapeo

Campo de ServiceNow

Origen en el JSON

Notas

state

1 fijo

Se define solo al crear. Las actualizaciones no reabren el incidente.

correlation_id

id

Se usa para evitar duplicados.

correlation_display

id

short_description

Data Leakage - Tipo - customer - user @ access.url

Limitado a 160 caracteres: solo se acorta la parte de usuario/URL (con ...).

description

Plantilla de la Figura 3b

Enlace: https://one.axur.com/data-leakage/credentials?customerId={customer}&text={id}

Etiquetas de tipo de credencial

credential.types

Etiqueta en el Incidente

employee

Employee credential exposed

user

User credential exposed

ambos

Employee and User credential exposed

La contraseña nunca se escribe en ServiceNow

El script no copia la contraseña al Incidente, aunque el feed la envíe. Los incidentes son visibles para muchas personas y se conservan por mucho tiempo, por lo que guardar allí contraseñas expuestas generaría una nueva filtración. Su equipo puede ver la detección completa en la Plataforma Axur mediante el enlace de la descripción.

Cuidado con las claves con punto

Campos como access.url y credential.types tienen un punto en el nombre. En JavaScript, use corchetes: d['access.url'], no d.access.url.


Script Include: el mapeador

Este script arma los campos y crea o actualiza el incidente. Se crea una sola vez, y lo usan tanto Push como Pull.

  1. Abra https://<instance>.service-now.com/sys_script_include.do?sys_id=-1. Desde el menú, la ruta es System Definition › Script Includes → New.

  2. Name: AxurCredentialFeedMapper (debe ser exactamente este nombre).

  3. Pegue el código de abajo en el campo Script y guarde.

var AxurCredentialFeedMapper = {
TABLE: 'incident',
CREDENTIALS_URL: 'https://one.axur.com/data-leakage/credentials',
SHORT_DESCRIPTION_LIMIT: 160,
WORKSPACE: 'Data Leakage',

TYPE_LABELS: {
'employee': 'Employee',
'user': 'User'
},

buildFields: function (item) {
var id = item.id;
var customer = item.customer || '';
var user = item.user || '';
var accessUrl = item['access.url'] || '';
var typeLabel = this.typeLabel(item['credential.types'] || []);

var prefix = this.WORKSPACE + ' - ' + typeLabel + ' credential exposed - ' + customer + ' - ';
var target = accessUrl ? user + ' @ ' + accessUrl : user;
var shortDescription = prefix + this.fit(target, prefix.length);

var link = this.CREDENTIALS_URL + '?customerId=' + encodeURIComponent(customer)
+ '&text=' + encodeURIComponent(id);

var description = [
'Axur - one.axur.com',
'',
'New credential exposure detected (' + link + ')',
'',
'Detection ID: ' + id,
this.assetsLine(item.assets || []),
'Credential Type: ' + typeLabel,
'User: ' + user + (item['user.type'] ? ' (' + item['user.type'] + ')' : ''),
'Access URL: ' + accessUrl,
'Source: ' + (item['source.name'] || ''),
'Status: ' + (item.status || ''),
'Detection Date: ' + this.formatDate(item.detectionDate || item.created)
].join('\n');

return { id: id, shortDescription: shortDescription, description: description };
},

typeLabel: function (types) {
var labels = [];
for (var i = 0; i < types.length; i++) {
labels.push(this.TYPE_LABELS[types[i]] || types[i]);
}
return labels.length ? labels.join(' and ') : 'Unknown';
},

fit: function (text, usedLength) {
var available = this.SHORT_DESCRIPTION_LIMIT - usedLength;
if (text.length <= available) return text;
return text.substring(0, Math.max(available - 3, 0)) + '...';
},

assetsLine: function (assets) {
if (assets.length === 0) return 'Asset: -';
return assets.length === 1 ? 'Asset: ' + assets[0] : 'Assets: (' + assets.join(', ') + ')';
},

formatDate: function (iso) {
if (!iso) return '';
return iso.substring(8, 10) + '/' + iso.substring(5, 7) + '/' + iso.substring(0, 4);
},

upsert: function (item) {
var f = this.buildFields(item);
if (!f.id) return;

var gr = new GlideRecord(this.TABLE);
gr.addQuery('correlation_id', f.id);
gr.query();
var exists = gr.next();
if (!exists) {
gr.initialize();
gr.state = 1;
}
gr.correlation_id = f.id;
gr.correlation_display = f.id;
gr.short_description = f.shortDescription;
gr.description = f.description;
if (exists) { gr.update(); } else { gr.insert(); }
},

processPayload: function (payload) {
var detections = (payload && payload.collectionData && payload.collectionData.detections) || [];
for (var i = 0; i < detections.length; i++) {
this.upsert(detections[i]);
}
return detections.length;
}
};

Opción A: Pull con un Scheduled Job

Elija esta opción si su instancia no puede recibir llamadas externas.

Guardar la URL y la API Key

Antes de empezar: tenga a mano la URL del feed y la API Key.

  1. Abra directamente el formulario de nueva propiedad: https://<instance>.service-now.com/sys_properties.do?sys_id=-1. También puede abrir sys_properties_list.do y hacer clic en New.

  2. Cree la propiedad de la URL del feed:

  3. Si axur.feed.api_key todavía no existe (se comparte con la integración del Tickets Feed), abra el formulario de nuevo y créela:

Seguridad

Nunca escriba la API Key directamente en el script. Si su equipo de seguridad lo prefiere, use Connection & Credential Aliases en lugar de la propiedad del sistema.

Crear la programación

  1. Abra https://<instance>.service-now.com/sysauto_script.do?sys_id=-1. Desde el menú, la ruta es System Definition › Scheduled Jobs → New → Automatically run a script of your choosing.

  2. Name: Axur Credentials Feed → Incident. Run: Periodically. Repeat interval: 00:05:00 (5 min).

  3. Pegue el script de abajo y guarde.

    Figura 4: Scheduled Job que se ejecuta cada 5 minutos (ilustración).

var FEED_URL = gs.getProperty('axur.credentials_feed.url');
var API_KEY = gs.getProperty('axur.feed.api_key');
var MAX_PAGES = 20;

for (var page = 0; page < MAX_PAGES; page++) {
var request = new sn_ws.RESTMessageV2();
request.setEndpoint(FEED_URL);
request.setHttpMethod('GET');
request.setRequestHeader('Authorization', 'Bearer ' + API_KEY);
request.setRequestHeader('Accept', 'application/json');

var response = request.execute();
if (response.getStatusCode() != 200) {
gs.error('Axur credentials feed: HTTP ' + response.getStatusCode() + ' - ' + response.getBody());
break;
}

var processed = AxurCredentialFeedMapper.processPayload(JSON.parse(response.getBody()));
if (processed === 0 || FEED_URL.indexOf('dry-run=true') > -1) break;
}

Cada llamada al feed avanza el puntero y devuelve el siguiente lote. El bucle continúa hasta que un lote llega vacío, con un límite de 20 llamadas por ejecución para que el job nunca se quede colgado. En modo dry-run el puntero no avanza, así que el job hace una sola llamada por ejecución.


Opción B: Push con una Scripted REST API

Elija esta opción para recibir credenciales casi en tiempo real. Su instancia debe aceptar llamadas entrantes de la Plataforma Axur.

  1. Abra https://<instance>.service-now.com/sys_ws_definition.do?sys_id=-1. Desde el menú, la ruta es System Web Services › Scripted Web Services › Scripted REST APIs → New.

  2. Name: Axur Credentials Feed, API ID: axur_credentials_feed. Guarde.

  3. En la pestaña Resources → New: Name credentials, HTTP method POST, Relative path /credentials.

  4. Pegue el script de abajo en el resource y guarde.

  5. Copie el Resource path (por ejemplo https://<instance>.service-now.com/api/<scope>/axur_credentials_feed/credentials) e ingréselo como endpoint del feed Push en la Plataforma Axur.

(function process(request, response) {
var processed = AxurCredentialFeedMapper.processPayload(request.body.data);
response.setStatus(200);
response.setBody({ processed: processed });
})(request, response);

Autenticación del endpoint

De forma predeterminada, el resource exige autenticación de ServiceNow (Requires authentication). No la desactive. En su lugar, haga que la Plataforma Axur se autentique en cada llamada:

  1. En ServiceNow, cree un usuario de integración dedicado (por ejemplo axur.integration) solo con los roles necesarios para crear y actualizar incidentes.

  2. Al configurar el feed Push en la Plataforma Axur, agregue un header personalizado con las credenciales de ese usuario: Authorization: Basic <base64 de usuario:contraseña>. La Plataforma Axur envía sus headers personalizados en cada solicitud.

Opcional: verificar la firma

Cada solicitud Push también incluye un header X-Push-Signature: un HMAC-SHA256 del cuerpo sin procesar de la solicitud, codificado en hexadecimal y calculado con la clave secreta del feed Push. Valídelo en el resource si su equipo de seguridad exige comprobar que la llamada proviene de la Plataforma Axur.

Prueba de conexión

Cuando guarda o prueba el feed Push, la Plataforma Axur envía un cuerpo vacío ({}). El script responde 200 con processed: 0 y no crea nada.


Probar y validar

  1. Active el dry-run temporalmente: abra la propiedad axur.credentials_feed.url (sys_properties_list.do, busque por nombre) y agregue ?dry-run=true al final de su Value, por ejemplo https://api.axur.com/gateway/1.0/api/integration-feed/feeds/feed/<ID>?dry-run=true. Guarde. Ahora el feed devuelve las mismas credenciales en cada llamada y su puntero no avanza, así que no se pierde nada mientras prueba.

  2. Ejecute el job manualmente: abra el Scheduled Job → Execute Now.

  3. Revise los incidentes en incident_list.do?sysparm_query=correlation_idISNOTEMPTY. Confirme que ninguna contraseña aparece en el Incidente.

  4. Ejecútelo de nuevo. Gracias al upsert, la cantidad de incidentes no debería aumentar.

  5. Busque errores en syslog_list.do o en System Logs › Errors (mensajes que empiezan con Axur credentials feed:).

  6. ¿Todo bien? Edite de nuevo axur.credentials_feed.url y quite ?dry-run=true de su valor, para que el puntero empiece a avanzar.

Consejo

Valide en una instancia de preproducción o de desarrollo antes de activarlo en producción. Un feed sin filtros puede traer muchas credenciales en la primera ejecución; empiece con un filtro (por ejemplo credential.types=employee) si espera un volumen grande.


Notas de seguridad y checklist

Tema

Recomendación

Contraseñas

Nunca se guardan en ServiceNow. Use el parámetro fields (paso 2.1) para que ni siquiera se envíen.

Quién ve los incidentes

Las credenciales expuestas son datos personales. Asigne los incidentes a un grupo restringido (por ejemplo, con una regla de Assignment group) en lugar de la cola general.

API Key

Guardada como password2, legible solo por admin y creada por un usuario de integración dedicado.

Checklist de puesta en producción

  • Credentials Feed creado en la Plataforma Axur con los filtros correctos y el parámetro fields

  • Script Include AxurCredentialFeedMapper creado

  • Pull: propiedades axur.credentials_feed.url y axur.feed.api_key creadas

  • Pull: Scheduled Job activo · Push: endpoint registrado en el feed

  • Probado con ?dry-run=true en axur.credentials_feed.url, sin duplicados y sin contraseñas en el Incidente

  • ?dry-run=true eliminado de axur.credentials_feed.url

¿Ha quedado contestada tu pregunta?