Skip to content

Commit c602c8f

Browse files
[8.18] [ML] Improving anomaly charts object safety (#217552) (#218835)
# Backport This will backport the following commits from `main` to `8.18`: - [[ML] Improving anomaly charts object safety (#217552)](#217552) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"James Gowdy","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-04-22T14:52:12Z","message":"[ML] Improving anomaly charts object safety (#217552)\n\nAdds checks for the values `__proto__` and `prototype` when reading\ndetector fields to reduce the risk of prototype pollution.","sha":"60af3ff3d525e830812b0986825d23d7041bef63","branchLabelMapping":{"^v9.1.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix",":ml","Feature:Anomaly Detection","backport:version","v9.1.0","v8.19.0","v8.18.1","v9.0.1","v8.17.6"],"title":"[ML] Improving anomaly charts object safety","number":217552,"url":"https://github.com/elastic/kibana/pull/217552","mergeCommit":{"message":"[ML] Improving anomaly charts object safety (#217552)\n\nAdds checks for the values `__proto__` and `prototype` when reading\ndetector fields to reduce the risk of prototype pollution.","sha":"60af3ff3d525e830812b0986825d23d7041bef63"}},"sourceBranch":"main","suggestedTargetBranches":["8.19","8.18","9.0","8.17"],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/217552","number":217552,"mergeCommit":{"message":"[ML] Improving anomaly charts object safety (#217552)\n\nAdds checks for the values `__proto__` and `prototype` when reading\ndetector fields to reduce the risk of prototype pollution.","sha":"60af3ff3d525e830812b0986825d23d7041bef63"}},{"branch":"8.19","label":"v8.19.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.18","label":"v8.18.1","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"9.0","label":"v9.0.1","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.17","label":"v8.17.6","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: James Gowdy <[email protected]>
1 parent 5642748 commit c602c8f

File tree

1 file changed

+38
-18
lines changed

1 file changed

+38
-18
lines changed

x-pack/platform/plugins/shared/ml/server/models/results_service/anomaly_charts.ts

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,11 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu
531531
record.partition_field_name ?? record.by_field_name ?? record.over_field_name;
532532
const firstFieldValue =
533533
record.partition_field_value ?? record.by_field_value ?? record.over_field_value;
534+
535+
if (fieldsSafe([firstFieldName, firstFieldValue]) === false) {
536+
return;
537+
}
538+
534539
if (firstFieldName !== undefined && firstFieldValue !== undefined) {
535540
const groupsForDetector = detectorsForJob[detectorIndex];
536541

@@ -567,25 +572,31 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu
567572
const secondFieldName = record.over_field_name ?? record.by_field_name;
568573
const secondFieldValue = record.over_field_value ?? record.by_field_value;
569574

570-
if (secondFieldName !== undefined && secondFieldValue !== undefined) {
571-
if (dataForGroupValue[secondFieldName] === undefined) {
572-
dataForGroupValue[secondFieldName] = Object.create(null);
573-
}
575+
if (
576+
secondFieldName === undefined ||
577+
secondFieldValue === undefined ||
578+
fieldsSafe([secondFieldName, secondFieldValue]) === false
579+
) {
580+
return;
581+
}
574582

575-
const splitsForGroup = dataForGroupValue[secondFieldName];
576-
if (splitsForGroup[secondFieldValue] === undefined) {
577-
splitsForGroup[secondFieldValue] = Object.create(null);
578-
}
583+
if (dataForGroupValue[secondFieldName] === undefined) {
584+
dataForGroupValue[secondFieldName] = Object.create(null);
585+
}
579586

580-
const dataForSplitValue = splitsForGroup[secondFieldValue];
581-
if (dataForSplitValue.maxScoreRecord === undefined) {
587+
const splitsForGroup = dataForGroupValue[secondFieldName];
588+
if (splitsForGroup[secondFieldValue] === undefined) {
589+
splitsForGroup[secondFieldValue] = Object.create(null);
590+
}
591+
592+
const dataForSplitValue = splitsForGroup[secondFieldValue];
593+
if (dataForSplitValue.maxScoreRecord === undefined) {
594+
dataForSplitValue.maxScore = record.record_score;
595+
dataForSplitValue.maxScoreRecord = record;
596+
} else {
597+
if (record.record_score > dataForSplitValue.maxScore) {
582598
dataForSplitValue.maxScore = record.record_score;
583599
dataForSplitValue.maxScoreRecord = record;
584-
} else {
585-
if (record.record_score > dataForSplitValue.maxScore) {
586-
dataForSplitValue.maxScore = record.record_score;
587-
dataForSplitValue.maxScoreRecord = record;
588-
}
589600
}
590601
}
591602
}
@@ -648,6 +659,15 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu
648659
return { records: recordsForSeries, errors: errorMessages };
649660
}
650661

662+
function fieldsSafe(fields: Array<string | number | undefined>) {
663+
return fields.every((field) => {
664+
if (typeof field === 'string') {
665+
return field !== '__proto__' && field !== 'prototype';
666+
}
667+
return true;
668+
});
669+
}
670+
651671
function buildConfigFromDetector(job: MlJob, detectorIndex: number) {
652672
const analysisConfig = job.analysis_config;
653673
const detector = analysisConfig.detectors[detectorIndex];
@@ -948,9 +968,9 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu
948968
(record) => (record.function_description || record.function) === ML_JOB_AGGREGATION.LAT_LONG
949969
);
950970

951-
const seriesConfigs = recordsToPlot.map((record) =>
952-
buildConfig(record, combinedJobRecords[record.job_id])
953-
);
971+
const seriesConfigs = recordsToPlot
972+
.filter((record) => record.job_id !== undefined)
973+
.map((record) => buildConfig(record, combinedJobRecords[record.job_id]));
954974

955975
const seriesConfigsNoGeoData = [];
956976

0 commit comments

Comments
 (0)