diff --git a/x-pack/plugins/ml/server/models/results_service/build_anomaly_table_items.js b/x-pack/plugins/ml/server/models/results_service/build_anomaly_table_items.js index 306f04c7ca95c..8ffe9fb71bcdb 100644 --- a/x-pack/plugins/ml/server/models/results_service/build_anomaly_table_items.js +++ b/x-pack/plugins/ml/server/models/results_service/build_anomaly_table_items.js @@ -125,7 +125,7 @@ function aggregateAnomalies(anomalyRecords, interval, dateFormatTz) { return []; } - const aggregatedData = {}; + const aggregatedData = Object.create(null); anomalyRecords.forEach((record) => { // Use moment.js to get start of interval. const roundedTime = @@ -133,27 +133,32 @@ function aggregateAnomalies(anomalyRecords, interval, dateFormatTz) { ? moment(record.timestamp).tz(dateFormatTz).startOf(interval).valueOf() : moment(record.timestamp).startOf(interval).valueOf(); if (aggregatedData[roundedTime] === undefined) { - aggregatedData[roundedTime] = {}; + aggregatedData[roundedTime] = Object.create(null); } // Aggregate by job, then detectorIndex. const jobId = record.job_id; const jobsAtTime = aggregatedData[roundedTime]; - if (jobsAtTime[jobId] === undefined) { - jobsAtTime[jobId] = {}; + if (jobsAtTime[jobId] === undefined || Object.hasOwn(jobsAtTime, jobId) === false) { + jobsAtTime[jobId] = Object.create(null); } // Aggregate by detector - default to function_description if no description available. const detectorIndex = record.detector_index; + if (typeof detectorIndex !== 'number') { + return; + } const detectorsForJob = jobsAtTime[jobId]; if (detectorsForJob[detectorIndex] === undefined) { - detectorsForJob[detectorIndex] = {}; + detectorsForJob[detectorIndex] = Object.create(null); } // Now add an object for the anomaly with the highest anomaly score per entity. // For the choice of entity, look in order for byField, overField, partitionField. // If no by/over/partition, default to an empty String. - const entitiesForDetector = detectorsForJob[detectorIndex]; + const entitiesForDetector = Object.hasOwn(detectorsForJob, detectorIndex) + ? detectorsForJob[detectorIndex] + : Object.create(null); // TODO - are we worried about different byFields having the same // value e.g. host=server1 and machine=server1? @@ -163,7 +168,7 @@ function aggregateAnomalies(anomalyRecords, interval, dateFormatTz) { } if (entitiesForDetector[entity] === undefined) { entitiesForDetector[entity] = record; - } else { + } else if (Object.hasOwn(entitiesForDetector, entity)) { if (record.record_score > entitiesForDetector[entity].record_score) { entitiesForDetector[entity] = record; }