Skip to content

Commit ca247fd

Browse files
author
Lucas Akira Uehara
committed
fix: Prototype Pollution Vulnerability Affecting redoc <=2.2.0
#2499
1 parent 85b622f commit ca247fd

File tree

3 files changed

+62
-33
lines changed

3 files changed

+62
-33
lines changed

package-lock.json

Lines changed: 30 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/utils/__tests__/helpers.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,30 @@ describe('Utils', () => {
7171
const obj2 = { a: ['C'], b: ['D'] };
7272
expect(mergeObjects({}, obj1, obj2)).toEqual({ a: ['C'], b: ['D'] });
7373
});
74+
test('should prevent prototype pollution', () => {
75+
const target = {};
76+
const source = JSON.parse('{"__proto__": {"polluted": "yes"}}');
77+
78+
mergeObjects(target, source);
79+
80+
expect(({} as any).polluted).toBeUndefined();
81+
});
82+
test('should merge objects correctly', () => {
83+
const target = { a: 1 };
84+
const source = { b: 2 };
85+
86+
const result = mergeObjects(target, source);
87+
88+
expect(result).toEqual({ a: 1, b: 2 });
89+
});
90+
test('should handle nested objects', () => {
91+
const target = { a: { b: 1 } };
92+
const source = { a: { c: 2 } };
93+
94+
const result = mergeObjects(target, source);
95+
96+
expect(result).toEqual({ a: { b: 1, c: 2 } });
97+
});
7498
});
7599

76100
describe('titleize', () => {

src/utils/helpers.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ export function appendToMdHeading(md: string, heading: string, content: string)
8181
}
8282
}
8383

84-
// credits https://stackoverflow.com/a/46973278/1749888
8584
export const mergeObjects = (target: any, ...sources: any[]): any => {
8685
if (!sources.length) {
8786
return target;
@@ -93,13 +92,15 @@ export const mergeObjects = (target: any, ...sources: any[]): any => {
9392

9493
if (isMergebleObject(target) && isMergebleObject(source)) {
9594
Object.keys(source).forEach((key: string) => {
96-
if (isMergebleObject(source[key])) {
97-
if (!target[key]) {
98-
target[key] = {};
95+
if (Object.prototype.hasOwnProperty.call(source, key) && key !== '__proto__') {
96+
if (isMergebleObject(source[key])) {
97+
if (!target[key]) {
98+
target[key] = {};
99+
}
100+
mergeObjects(target[key], source[key]);
101+
} else {
102+
target[key] = source[key];
99103
}
100-
mergeObjects(target[key], source[key]);
101-
} else {
102-
target[key] = source[key];
103104
}
104105
});
105106
}

0 commit comments

Comments
 (0)