Skip to content

Commit 92d926d

Browse files
fix: replace lodash.get with safeGet helper to prevent prototype pollution (#10987)
* feat: replace lodash.get with safeGet helper to prevent prototype pollution Signed-off-by: Yulong Ruan <[email protected]> * Changeset file for PR #10987 created/updated --------- Signed-off-by: Yulong Ruan <[email protected]> Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com>
1 parent a47de88 commit 92d926d

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

changelogs/fragments/10987.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
fix:
2+
- Replace lodash.get with safeGet helper to prevent prototype pollution ([#10987](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/10987))

src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_sibling_agg_value.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,12 @@
2929
*/
3030

3131
import _ from 'lodash';
32+
import { safeGet } from './safe_get';
3233

3334
export const getSiblingAggValue = (row, metric) => {
3435
let key = metric.type.replace(/_bucket$/, '');
3536
if (key === 'std_deviation' && _.includes(['upper', 'lower'], metric.mode)) {
3637
key = `std_deviation_bounds.${metric.mode}`;
3738
}
38-
return _.get(row, `${metric.id}.${key}`);
39+
return safeGet(row, `${metric.id}.${key}`);
3940
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
// A safe get function that blocks prototype access
7+
export function safeGet(object, path, defaultValue) {
8+
const pathArray = Array.isArray(path) ? path : path.split('.');
9+
10+
// Block dangerous prototype pollution paths
11+
const dangerousPaths = ['__proto__', 'constructor', 'prototype'];
12+
for (const segment of pathArray) {
13+
if (dangerousPaths.includes(segment)) {
14+
return defaultValue;
15+
}
16+
}
17+
18+
// Use standard property access instead of lodash.get
19+
let result = object;
20+
for (const key of pathArray) {
21+
if (result == null || typeof result !== 'object') {
22+
return defaultValue;
23+
}
24+
// Only access own properties, not inherited ones
25+
if (!Object.prototype.hasOwnProperty.call(result, key)) {
26+
return defaultValue;
27+
}
28+
result = result[key];
29+
}
30+
return result !== undefined ? result : defaultValue;
31+
}

0 commit comments

Comments
 (0)