(function process(request, response) { var parseRequestBody = function(bodyString) { return JSON.parse(bodyString); }; var buildDescriptionForAG = function(requestBody) { var description = ''; description += 'Severity: ' + requestBody.severity + '\n'; description += 'Reason: ' + JSON.parse(requestBody.extra_data).reason + '\n'; return description; }; var buildShortDescriptionForAG = function(requestBody) { return 'Airgap ' + requestBody.severity + ' alert with alarm code ' + requestBody.code; }; var buildDescriptionForOriginal = function(requestBody) { var description = '\nUser Information:\n'; description += requestBody.userName + '\n'; description += requestBody.user + '\n'; description += 'Severity: ' + requestBody.severity + '\n'; description += 'State: ' + requestBody.state + '\n'; if (requestBody.clientIPs && requestBody.clientIPs.length > 0) { var clientList = requestBody.clientIPs.join('\n'); description += '\nNetwork Client Information:\n' + clientList + '\n'; } if (requestBody.files && requestBody.files.length > 0) { var truncatedFiles = requestBody.files.slice(0, 10); var fileListDescription = truncatedFiles.join('\n'); description += '\nAffected Files: \n' + fileListDescription; } return description; }; var findExistingIncidentBySubject = function(searchString) { var gr = new GlideRecord('sn_si_incident'); gr.addQuery('short_description', 'CONTAINS', searchString); // Search by the searchString in the subject gr.query(); if (gr.next()) { return gr; } else { return null; } }; var updateIncidentNotes = function(secIncident, requestBody) { var additionalNotes = '\nUpdate from Original Alert Payload:\n'; additionalNotes += buildDescriptionForOriginal(requestBody); secIncident.comments += additionalNotes; secIncident.update(); }; var findOrCreateHostCI = function(ipAddress) { var ciGr = new GlideRecord('cmdb_ci_computer'); ciGr.addQuery('ip_address', ipAddress); ciGr.query(); if (ciGr.next()) { return ciGr.sys_id; } else { var newCI = new GlideRecord('cmdb_ci_computer'); newCI.initialize(); newCI.name = 'NAS Connected host ' + ipAddress; newCI.ip_address = ipAddress; newCI.short_description = 'Superna Security Edition Created CI'; var newCISysId = newCI.insert(); return newCISysId; } }; var findOrCreateUser = function(userName) { var userGr = new GlideRecord('sys_user'); userGr.addQuery('user_name', userName); userGr.query(); if (userGr.next()) { return userGr.sys_id; } else { var newUser = new GlideRecord('sys_user'); newUser.initialize(); newUser.user_name = userName; var newSysId = newUser.insert(); return newSysId; } }; var detectPayloadType = function(requestBody) { // Detect AG0008 payload based on presence of "code" and format if (requestBody.code && requestBody.code.startsWith('AG')) { return 'AG0008'; } else { return 'Original'; } }; var setIncidentSeverity = function(secIncident, severity) { var severityMap = { "CRITICAL": { impact: 1, urgency: 1, priority: 1 }, "MAJOR": { impact: 1, urgency: 2, priority: 2 }, "MONITOR": { impact: 2, urgency: 3, priority: 3 }, "WARNING": { impact: 3, urgency: 3, priority: 4 } }; if (severityMap[severity]) { secIncident.impact = severityMap[severity].impact; secIncident.urgency = severityMap[severity].urgency; secIncident.priority = severityMap[severity].priority; } }; var requestBody = parseRequestBody(request.body.dataString); var payloadType = detectPayloadType(requestBody); var secIncident; var sysId; if (payloadType === 'AG0008') { // Handle AG0008 payload var eventCode = requestBody.code; secIncident = findExistingIncidentBySubject(eventCode); // Search for Airgap incidents by alarm code in the subject var isNewIncident = !secIncident; if (isNewIncident) { secIncident = new GlideRecord('sn_si_incident'); secIncident.short_description = buildShortDescriptionForAG(requestBody); // Store code and severity in the subject secIncident.caller_id = 'eyeglass'; secIncident.category = 'security'; secIncident.subcategory = 'ransomware'; var hostCISysId = findOrCreateHostCI(requestBody.sync_key); secIncident.cmdb_ci = hostCISysId; secIncident.description = buildDescriptionForAG(requestBody); secIncident.comments = secIncident.description; secIncident.u_clientIPs = requestBody.sync_key; setIncidentSeverity(secIncident, requestBody.severity); sysId = secIncident.insert(); gs.info('@@@ New Airgap Security Incident created. Sys ID: ' + sysId); } else { // Update existing incident's notes updateIncidentNotes(secIncident, requestBody); sysId = secIncident.sys_id; gs.info('@@@ Airgap Security Incident updated with new payload data. Sys ID: ' + sysId); } } else { // Handle original payload var eventId = '#' + requestBody.id; var searchString = 'Security Alert - ' + requestBody.id; // Construct a more precise search string secIncident = findExistingIncidentBySubject(searchString); // Search for Original incidents by event ID in the subject var isNewIncident = !secIncident; if (isNewIncident) { secIncident = new GlideRecord('sn_si_incident'); secIncident.short_description = 'Security Alert - ' + requestBody.id + ' - Affected User ' + requestBody.userName; secIncident.caller_id = 'eyeglass'; secIncident.category = 'security'; secIncident.subcategory = 'ransomware'; // Find or create the host CI by IP address if (requestBody.clientIPs && requestBody.clientIPs.length > 0) { var hostCISysId = findOrCreateHostCI(requestBody.clientIPs[0]); // Use the first IP secIncident.cmdb_ci = hostCISysId; // Set the affected CI } // Find or create user var userSysId = findOrCreateUser(requestBody.userName); secIncident.affected_user = userSysId; secIncident.description = buildDescriptionForOriginal(requestBody); secIncident.comments = secIncident.description; setIncidentSeverity(secIncident, requestBody.severity); sysId = secIncident.insert(); } else { // Update existing incident's notes for Original payload updateIncidentNotes(secIncident, requestBody); sysId = secIncident.sys_id; gs.info('@@@ Original Security Incident updated with new payload data. Sys ID: ' + sysId); } } if (sysId) { response.setStatus(201); response.setBody({ 'sys_id': sysId, 'number': secIncident.number, 'status': 'Open' }); } else { response.setStatus(500); response.setBody({ 'error': 'Failed to create or update Security Incident.' }); } })(request, response);