fix(common): keep StreamableFile error messages out of responses

On Express, the default StreamableFile error handler answered a stream
that failed before any data was sent with a 400 whose body was the
error's message. For a file that could not be opened, that is Node's
message with the file's absolute path (e.g. "ENOENT: no such file or
directory, open '/srv/reports/q3.csv'").

The handler now sends "Bad Request" and logs the error with the file's
error logger instead. Behaviour change: the status is still 400, but
the body no longer carries the error message, as the docs said it did.
Applications that want the message can send it with setErrorHandler().

Discovered by Anthropic's OSS Scanner, as vulnerability ANT-2026-99AVFK4K.
This commit is contained in:
Kamil Myśliwiec committed 2026-10-16 14:49:05 +02:00
1 parent 1933cc9edd
commit 2f28d91afb
2 files changed
+14 -5

No files matched your search

@@ -29,8 +29,11 @@ export class StreamableFile {
return;
}
// The message may name the path the stream reads from, so it is
// logged rather than sent.
this.logError(err);
res.statusCode = HttpStatus.BAD_REQUEST;
res.send(err.message);
res.send('Bad Request');
};
protected logError: (err: Error) => void = (err: Error) => {
@@ -118,9 +118,12 @@ describe('StreamableFile', () => {
expect(res.send).not.toHaveBeenCalled();
});
it('should set status code to BAD_REQUEST and send error message', () => {
it('should set status code to BAD_REQUEST and log the error instead of sending its message', () => {
const stream = new Readable();
const streamableFile = new StreamableFile(stream);
const errorLogger = vi.fn();
const streamableFile = new StreamableFile(stream).setErrorLogger(
errorLogger,
);
const res = {
destroyed: false,
headersSent: false,
@@ -128,12 +131,15 @@ describe('StreamableFile', () => {
end: vi.fn(),
send: vi.fn(),
};
const error = new Error('test error message');
const error = new Error(
"ENOENT: no such file or directory, open '/srv/reports/q3.csv'",
);
streamableFile.errorHandler(error, res as any);
expect(res.statusCode).toBe(HttpStatus.BAD_REQUEST);
expect(res.send).toHaveBeenCalledWith('test error message');
expect(res.send).toHaveBeenCalledWith('Bad Request');
expect(errorLogger).toHaveBeenCalledWith(error);
});
});
});