fix: File metadata endpoint bypasses beforeFind / afterFind trigger authorization ([GHSA-hwx8-q9cg-mqmc](https://github.com/parse-community/parse-server/security/advisories/GHSA-hwx8-q9cg-mqmc)) (#10107)

This commit is contained in:
Manuel
2026-03-06 01:05:25 +00:00
committed by GitHub
parent cf030af7f5
commit a7358b1e0c
2 changed files with 51 additions and 5 deletions
+15
View File
@@ -4473,6 +4473,21 @@ describe('Parse.File hooks', () => {
});
expect(response.headers['content-disposition']).toBe(`attachment;filename=${file._name}`);
});
it('beforeFind blocks metadata endpoint', async () => {
const file = new Parse.File('popeye.txt', [1, 2, 3], 'text/plain');
await file.save({ useMasterKey: true });
Parse.Cloud.beforeFind(Parse.File, () => {
throw 'unauthorized';
});
await expectAsync(
request({
url: `http://localhost:8378/1/files/test/metadata/${file._name}`,
}).catch(e => {
throw new Parse.Error(e.data.code, e.data.error);
})
).toBeRejectedWith(new Parse.Error(Parse.Error.SCRIPT_FAILED, 'unauthorized'));
});
});
describe('Cloud Config hooks', () => {
+36 -5
View File
@@ -317,14 +317,45 @@ export class FilesRouter {
async metadataHandler(req, res) {
try {
const config = Config.get(req.params.appId);
if (!config) {
res.status(200);
res.json({});
return;
}
const { filesController } = config;
const { filename } = req.params;
const data = await filesController.getMetadata(filename);
let { filename } = req.params;
const file = new Parse.File(filename, { base64: '' });
const triggerResult = await triggers.maybeRunFileTrigger(
triggers.Types.beforeFind,
{ file },
config,
req.auth
);
if (triggerResult?.file?._name) {
filename = triggerResult.file._name;
}
const data = await filesController.getMetadata(filename).catch(() => {
res.status(200);
res.json({});
});
if (!data) {
return;
}
await triggers.maybeRunFileTrigger(
triggers.Types.afterFind,
{ file },
config,
req.auth
);
res.status(200);
res.json(data);
} catch {
res.status(200);
res.json({});
} catch (e) {
const err = triggers.resolveError(e, {
code: Parse.Error.SCRIPT_FAILED,
message: 'Could not get file metadata.',
});
res.status(403);
res.json({ code: err.code, error: err.message });
}
}
}