Skip to content

Commit 4dc4349

Browse files
committed
proto
1 parent bf2104f commit 4dc4349

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

spec/CloudCodeMultipart.spec.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,4 +281,60 @@ describe('Cloud Code Multipart', () => {
281281

282282
expect(result.data.code).toBe(Parse.Error.INVALID_JSON);
283283
});
284+
285+
it('should not allow prototype pollution via __proto__ field name', async () => {
286+
Parse.Cloud.define('multipartProto', req => {
287+
const obj = {};
288+
return {
289+
polluted: obj.polluted !== undefined,
290+
paramsClean: Object.getPrototypeOf(req.params) === Object.prototype,
291+
};
292+
});
293+
294+
const boundary = '----TestBoundaryProto';
295+
const body = buildMultipartBody(boundary, [
296+
{ name: '__proto__', value: '{"polluted":"yes"}' },
297+
]);
298+
299+
const result = await postMultipart(
300+
`http://localhost:8378/1/functions/multipartProto`,
301+
{
302+
'Content-Type': `multipart/form-data; boundary=${boundary}`,
303+
'X-Parse-Application-Id': 'test',
304+
'X-Parse-REST-API-Key': 'rest',
305+
},
306+
body
307+
);
308+
309+
expect(result.status).toBe(200);
310+
expect(result.data.result.polluted).toBe(false);
311+
expect(result.data.result.paramsClean).toBe(true);
312+
});
313+
314+
it('should not grant master key access via multipart fields', async () => {
315+
const obj = new Parse.Object('SecretClass');
316+
await obj.save(null, { useMasterKey: true });
317+
318+
Parse.Cloud.define('multipartAuthCheck', req => {
319+
return { isMaster: req.master };
320+
});
321+
322+
const boundary = '----TestBoundaryAuth';
323+
const body = buildMultipartBody(boundary, [
324+
{ name: '_MasterKey', value: 'test' },
325+
]);
326+
327+
const result = await postMultipart(
328+
`http://localhost:8378/1/functions/multipartAuthCheck`,
329+
{
330+
'Content-Type': `multipart/form-data; boundary=${boundary}`,
331+
'X-Parse-Application-Id': 'test',
332+
'X-Parse-REST-API-Key': 'rest',
333+
},
334+
body
335+
);
336+
337+
expect(result.status).toBe(200);
338+
expect(result.data.result.isMaster).toBe(false);
339+
});
284340
});

src/Routers/FunctionsRouter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ export class FunctionsRouter extends PromiseRouter {
185185
}
186186
const maxBytes = Utils.parseSizeToBytes(req.config.maxUploadSize);
187187
return new Promise((resolve, reject) => {
188-
const fields = {};
188+
const fields = Object.create(null);
189189
let totalBytes = 0;
190190
let settled = false;
191191
let busboy;

0 commit comments

Comments
 (0)