Skip to content

Commit 4cf11dc

Browse files
authored
Merge pull request #3 from d3v53c/huntr/proto-01
Prototype pollution fix - checking magic attributes - grpc-js
2 parents 1e37fbd + 6101694 commit 4cf11dc

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

packages/grpc-js/src/make-client.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,15 @@ export interface ServiceClientConstructor {
9393
service: ServiceDefinition;
9494
}
9595

96+
/**
97+
* Returns true, if given key is included in the blacklisted
98+
* keys.
99+
* @param key key for check, string.
100+
*/
101+
function isPrototypePolluted(key: string): Boolean {
102+
return ['__proto__', 'prototype', 'constructor'].includes(key);
103+
}
104+
96105
/**
97106
* Creates a constructor for a client with the given methods, as specified in
98107
* the methods argument. The resulting class will have an instance method for
@@ -122,7 +131,7 @@ export function makeClientConstructor(
122131
}
123132

124133
Object.keys(methods).forEach((name) => {
125-
if (name === '__proto__') {
134+
if (isPrototypePolluted(name)) {
126135
return;
127136
}
128137
const attrs = methods[name];
@@ -155,7 +164,7 @@ export function makeClientConstructor(
155164
ServiceClientImpl.prototype[name] = methodFunc;
156165
// Associate all provided attributes with the method
157166
Object.assign(ServiceClientImpl.prototype[name], attrs);
158-
if (attrs.originalName && attrs.originalName !== '__proto__') {
167+
if (attrs.originalName && !isPrototypePolluted(attrs.originalName)) {
159168
ServiceClientImpl.prototype[attrs.originalName] =
160169
ServiceClientImpl.prototype[name];
161170
}
@@ -204,7 +213,7 @@ export function loadPackageDefinition(
204213
if (Object.prototype.hasOwnProperty.call(packageDef, serviceFqn)) {
205214
const service = packageDef[serviceFqn];
206215
const nameComponents = serviceFqn.split('.');
207-
if (nameComponents.some(comp => comp === '__proto__')) {
216+
if (nameComponents.some((comp: string) => isPrototypePolluted(comp))) {
208217
continue;
209218
}
210219
const serviceName = nameComponents[nameComponents.length - 1];

packages/grpc-js/test/test-prototype-pollution.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,8 @@ describe('loadPackageDefinition', () => {
2424
loadPackageDefinition({'__proto__.polluted': true} as any);
2525
assert.notStrictEqual(({} as any).polluted, true);
2626
});
27+
it('Should not allow prototype pollution #2', () => {
28+
loadPackageDefinition({'constructor.prototype.polluted': true} as any);
29+
assert.notStrictEqual(({} as any).polluted, true);
30+
});
2731
});

0 commit comments

Comments
 (0)