fix(core): Prevent DoS via malformed binary data ID (#16229)

This commit is contained in:
Iván Ovejero
2025-06-13 12:53:00 +02:00
committed by GitHub
parent 7177e3aab0
commit 43c52a8b4f
2 changed files with 32 additions and 5 deletions

View File

@@ -26,7 +26,7 @@ describe('BinaryDataController', () => {
await controller.get(request, response, query);
expect(response.status).toHaveBeenCalledWith(400);
expect(response.end).toHaveBeenCalledWith('Missing binary data mode');
expect(response.end).toHaveBeenCalledWith('Malformed binary data ID');
});
it('should return 400 if binary data mode is invalid', async () => {
@@ -152,6 +152,24 @@ describe('BinaryDataController', () => {
expect(result).toBe(stream);
expect(binaryDataService.getAsStream).toHaveBeenCalledWith('filesystem:123');
});
describe('with malicious binary data IDs', () => {
it.each([
['filesystem:'],
['filesystem-v2:'],
['filesystem:/'],
['filesystem-v2:/'],
['filesystem://'],
['filesystem-v2://'],
])('should return 400 for ID "%s"', async (maliciousId) => {
const query = { id: maliciousId, action: 'download' } as BinaryDataQueryDto;
await controller.get(request, response, query);
expect(response.status).toHaveBeenCalledWith(400);
expect(response.end).toHaveBeenCalledWith('Malformed binary data ID');
});
});
});
describe('getSigned', () => {
@@ -162,7 +180,7 @@ describe('BinaryDataController', () => {
await controller.getSigned(request, response, query);
expect(response.status).toHaveBeenCalledWith(400);
expect(response.end).toHaveBeenCalledWith('Missing binary data mode');
expect(response.end).toHaveBeenCalledWith('Malformed binary data ID');
});
it('should return 400 if binary data mode is invalid', async () => {

View File

@@ -47,14 +47,23 @@ export class BinaryDataController {
throw new BadRequestError('Missing binary data ID');
}
if (!binaryDataId.includes(':')) {
throw new BadRequestError('Missing binary data mode');
const separatorIndex = binaryDataId.indexOf(':');
if (separatorIndex === -1) {
throw new BadRequestError('Malformed binary data ID');
}
const [mode] = binaryDataId.split(':');
const mode = binaryDataId.substring(0, separatorIndex);
if (!isValidNonDefaultMode(mode)) {
throw new BadRequestError('Invalid binary data mode');
}
const path = binaryDataId.substring(separatorIndex + 1);
if (path === '' || path === '/' || path === '//') {
throw new BadRequestError('Malformed binary data ID');
}
}
private async setContentHeaders(