Skip to content

Commit 4c9e956

Browse files
authored
fix: invalid file request not properly handled [skip release] (#8062)
1 parent 75af9a2 commit 4c9e956

File tree

5 files changed

+56
-5
lines changed

5 files changed

+56
-5
lines changed

changelogs/CHANGELOG_release.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## [5.2.3](https://github.com/parse-community/parse-server/compare/5.2.2...5.2.3) (2022-06-17)
2+
3+
4+
### Bug Fixes
5+
6+
* invalid file request not properly handled; this fixes a security vulnerability in which an invalid file request can crash the server ([GHSA-xw6g-jjvf-wwf9](https://github.com/parse-community/parse-server/security/advisories/GHSA-xw6g-jjvf-wwf9)) ([#8060](https://github.com/parse-community/parse-server/issues/8060)) ([5be375d](https://github.com/parse-community/parse-server/commit/5be375dec2fa35425c1003ae81c55995ac72af92))
7+
18
## [5.2.2](https://github.com/parse-community/parse-server/compare/5.2.1...5.2.2) (2022-06-17)
29

310

package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "parse-server",
3-
"version": "5.2.2",
3+
"version": "5.2.3",
44
"description": "An express module providing a Parse-compatible API server",
55
"main": "lib/index.js",
66
"repository": {

spec/ParseFile.spec.js

+38
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,44 @@ describe('Parse.File testing', () => {
654654
});
655655
});
656656

657+
describe('getting files', () => {
658+
it('does not crash on file request with invalid app ID', async () => {
659+
const res1 = await request({
660+
url: 'http://localhost:8378/1/files/invalid-id/invalid-file.txt',
661+
}).catch(e => e);
662+
expect(res1.status).toBe(403);
663+
expect(res1.data).toEqual({ code: 119, error: 'Invalid application ID.' });
664+
// Ensure server did not crash
665+
const res2 = await request({ url: 'http://localhost:8378/1/health' });
666+
expect(res2.status).toEqual(200);
667+
expect(res2.data).toEqual({ status: 'ok' });
668+
});
669+
670+
it('does not crash on file request with invalid path', async () => {
671+
const res1 = await request({
672+
url: 'http://localhost:8378/1/files/invalid-id//invalid-path/%20/invalid-file.txt',
673+
}).catch(e => e);
674+
expect(res1.status).toBe(403);
675+
expect(res1.data).toEqual({ error: 'unauthorized' });
676+
// Ensure server did not crash
677+
const res2 = await request({ url: 'http://localhost:8378/1/health' });
678+
expect(res2.status).toEqual(200);
679+
expect(res2.data).toEqual({ status: 'ok' });
680+
});
681+
682+
it('does not crash on file metadata request with invalid app ID', async () => {
683+
const res1 = await request({
684+
url: `http://localhost:8378/1/files/invalid-id/metadata/invalid-file.txt`,
685+
});
686+
expect(res1.status).toBe(200);
687+
expect(res1.data).toEqual({});
688+
// Ensure server did not crash
689+
const res2 = await request({ url: 'http://localhost:8378/1/health' });
690+
expect(res2.status).toEqual(200);
691+
expect(res2.data).toEqual({ status: 'ok' });
692+
});
693+
});
694+
657695
xdescribe('Gridstore Range tests', () => {
658696
it('supports range requests', done => {
659697
const headers = {

src/Routers/FilesRouter.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ export class FilesRouter {
6666

6767
getHandler(req, res) {
6868
const config = Config.get(req.params.appId);
69+
if (!config) {
70+
res.status(403);
71+
const err = new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Invalid application ID.');
72+
res.json({ code: err.code, error: err.message });
73+
return;
74+
}
6975
const filesController = config.filesController;
7076
const filename = req.params.filename;
7177
const contentType = mime.getType(filename);
@@ -245,10 +251,10 @@ export class FilesRouter {
245251
}
246252

247253
async metadataHandler(req, res) {
248-
const config = Config.get(req.params.appId);
249-
const { filesController } = config;
250-
const { filename } = req.params;
251254
try {
255+
const config = Config.get(req.params.appId);
256+
const { filesController } = config;
257+
const { filename } = req.params;
252258
const data = await filesController.getMetadata(filename);
253259
res.status(200);
254260
res.json(data);

0 commit comments

Comments
 (0)