Skip to content

Commit 20fc61b

Browse files
Fix lodash __proto__ path blocking in dependency injection crawler
lodash 4.17.21 blocks __proto__ in _.set/_.get for prototype pollution protection. Replace with custom safeSet/safeGet that can traverse prototype chains safely for DI function injection. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 5ad11c7 commit 20fc61b

1 file changed

Lines changed: 23 additions & 3 deletions

File tree

src/recorder/injection/param-crawler.js

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,26 @@ const {
99
CLS_NAMESPACE,
1010
} = require('../../util/constants');
1111

12+
// lodash _.set blocks __proto__ paths for security (prototype pollution).
13+
// We need a custom setter that can traverse prototype chains safely.
14+
const safeSet = (obj, path, value) => {
15+
let current = obj;
16+
for (let i = 0; i < path.length - 1; i += 1) {
17+
current = current[path[i]];
18+
}
19+
current[path[path.length - 1]] = value;
20+
};
21+
22+
// lodash _.get also blocks __proto__ paths in newer versions.
23+
const safeGet = (obj, path, defaultValue) => {
24+
let current = obj;
25+
for (let i = 0; i < path.length; i += 1) {
26+
if (current == null) return defaultValue;
27+
current = current[path[i]];
28+
}
29+
return current !== undefined ? current : defaultValue;
30+
};
31+
1232
const injectDependencyInjections = (params) => {
1333
const session = getNamespace(CLS_NAMESPACE);
1434
const stack = session.get('stack');
@@ -24,17 +44,17 @@ const injectDependencyInjections = (params) => {
2444
path !== undefined;
2545
path = iterator.next().value
2646
) {
27-
const existingProperty = _.get(param, path);
47+
const existingProperty = safeGet(param, path);
2848
const lIndex = path.length - 1;
2949
const newFnName = newFunctionNameGenerator(path[lIndex], fileName);
3050
const newPath = _.clone(path);
3151
newPath[lIndex] = newFnName;
3252
const fppkey = path.join('.');
33-
const propertyToInject = _.get(param, newPath, existingProperty);
53+
const propertyToInject = safeGet(param, newPath, existingProperty);
3454
const injectedProperty = injectFunctionDynamically(
3555
propertyToInject, paramIndex, fppkey,
3656
);
37-
_.set(param, newPath, injectedProperty);
57+
safeSet(param, newPath, injectedProperty);
3858
}
3959
} else {
4060
params[paramIndex] = injectFunctionDynamically(

0 commit comments

Comments
 (0)