elastic / kibana

Your window into the Elastic Stack
https://www.elastic.co/products/kibana
Other
19.69k stars 8.12k forks source link

[ResponseOps][Connectors] Possible to open close incident in ServiceNow #184646

Open cnasikas opened 3 months ago

cnasikas commented 3 months ago

We got an SDH where it was possible to create new issues in ServiceNow with the state as closed due to race conditions. Taking a look at the following code

const { correlationId, incidentId } = params;
      let incidentToBeClosed = null;

      if (correlationId == null && incidentId == null) {
        throw new Error('No correlationId or incidentId found.');
      }

      if (incidentId) {
        incidentToBeClosed = await getIncident(incidentId);
      } else if (correlationId) {
        incidentToBeClosed = await getIncidentByCorrelationId(correlationId);
      }

      if (incidentToBeClosed === null) {
        logger.warn(
          `[ServiceNow][CloseIncident] No incident found with correlation_id: ${correlationId} or incidentId: ${incidentId}.`
        );

        return null;
      }

      if (incidentToBeClosed.state === '7') {
        logger.warn(
          `[ServiceNow][CloseIncident] Incident with correlation_id: ${correlationId} or incidentId: ${incidentId} is closed.`
        );

        return {
          title: incidentToBeClosed.number,
          id: incidentToBeClosed.sys_id,
          pushedDate: getPushedDate(incidentToBeClosed.sys_updated_on),
          url: getIncidentViewURL(incidentToBeClosed.sys_id),
        };
      }

      const closedIncident = await updateIncident({
        incidentId: incidentToBeClosed.sys_id,
        incident: {
          state: '7', // used for "closed" status in serviceNow
          close_code: 'Closed/Resolved by Caller',
          close_notes: 'Closed by Caller',
        },
      });

      return closedIncident;

we can see that for this to happen the incidentToBeClosed === null checks need to be bypassed so the await updateIncident({...}) can be called. This is possible only if getIncident or getIncidentByCorrelationId returns {}. This is possible if the user does not have permission on all records of the incident table (ServiceNow will return an empty object in this case). A possible fix would be to do the check as incidentToBeClosed == null || isEmpty(incidentToBeClosed) || isEmpty(incidentToBeClosed.sys_id).

elasticmachine commented 3 months ago

Pinging @elastic/response-ops (Team:ResponseOps)