fix: 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)) (#8059)
This commit is contained in:
@@ -623,6 +623,44 @@ describe('Parse.File testing', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getting files', () => {
|
||||||
|
it('does not crash on file request with invalid app ID', async () => {
|
||||||
|
const res1 = await request({
|
||||||
|
url: 'http://localhost:8378/1/files/invalid-id/invalid-file.txt',
|
||||||
|
}).catch(e => e);
|
||||||
|
expect(res1.status).toBe(403);
|
||||||
|
expect(res1.data).toEqual({ code: 119, error: 'Invalid application ID.' });
|
||||||
|
// Ensure server did not crash
|
||||||
|
const res2 = await request({ url: 'http://localhost:8378/1/health' });
|
||||||
|
expect(res2.status).toEqual(200);
|
||||||
|
expect(res2.data).toEqual({ status: 'ok' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not crash on file request with invalid path', async () => {
|
||||||
|
const res1 = await request({
|
||||||
|
url: 'http://localhost:8378/1/files/invalid-id//invalid-path/%20/invalid-file.txt',
|
||||||
|
}).catch(e => e);
|
||||||
|
expect(res1.status).toBe(403);
|
||||||
|
expect(res1.data).toEqual({ error: 'unauthorized' });
|
||||||
|
// Ensure server did not crash
|
||||||
|
const res2 = await request({ url: 'http://localhost:8378/1/health' });
|
||||||
|
expect(res2.status).toEqual(200);
|
||||||
|
expect(res2.data).toEqual({ status: 'ok' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not crash on file metadata request with invalid app ID', async () => {
|
||||||
|
const res1 = await request({
|
||||||
|
url: `http://localhost:8378/1/files/invalid-id/metadata/invalid-file.txt`,
|
||||||
|
});
|
||||||
|
expect(res1.status).toBe(200);
|
||||||
|
expect(res1.data).toEqual({});
|
||||||
|
// Ensure server did not crash
|
||||||
|
const res2 = await request({ url: 'http://localhost:8378/1/health' });
|
||||||
|
expect(res2.status).toEqual(200);
|
||||||
|
expect(res2.data).toEqual({ status: 'ok' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
xdescribe('Gridstore Range tests', () => {
|
xdescribe('Gridstore Range tests', () => {
|
||||||
it('supports range requests', done => {
|
it('supports range requests', done => {
|
||||||
const headers = {
|
const headers = {
|
||||||
|
|||||||
@@ -66,6 +66,12 @@ export class FilesRouter {
|
|||||||
|
|
||||||
getHandler(req, res) {
|
getHandler(req, res) {
|
||||||
const config = Config.get(req.params.appId);
|
const config = Config.get(req.params.appId);
|
||||||
|
if (!config) {
|
||||||
|
res.status(403);
|
||||||
|
const err = new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Invalid application ID.');
|
||||||
|
res.json({ code: err.code, error: err.message });
|
||||||
|
return;
|
||||||
|
}
|
||||||
const filesController = config.filesController;
|
const filesController = config.filesController;
|
||||||
const filename = req.params.filename;
|
const filename = req.params.filename;
|
||||||
const contentType = mime.getType(filename);
|
const contentType = mime.getType(filename);
|
||||||
@@ -222,10 +228,10 @@ export class FilesRouter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async metadataHandler(req, res) {
|
async metadataHandler(req, res) {
|
||||||
const config = Config.get(req.params.appId);
|
|
||||||
const { filesController } = config;
|
|
||||||
const { filename } = req.params;
|
|
||||||
try {
|
try {
|
||||||
|
const config = Config.get(req.params.appId);
|
||||||
|
const { filesController } = config;
|
||||||
|
const { filename } = req.params;
|
||||||
const data = await filesController.getMetadata(filename);
|
const data = await filesController.getMetadata(filename);
|
||||||
res.status(200);
|
res.status(200);
|
||||||
res.json(data);
|
res.json(data);
|
||||||
|
|||||||
Reference in New Issue
Block a user