test(#838): reject chunked garbage and redact tokens
This commit is contained in:
@@ -24,8 +24,13 @@ async function scriptedBroker(
|
|||||||
connections += 1;
|
connections += 1;
|
||||||
socket.once('end', () => {
|
socket.once('end', () => {
|
||||||
if (chunks === 'hang') return;
|
if (chunks === 'hang') return;
|
||||||
for (const chunk of chunks) socket.write(chunk);
|
void (async () => {
|
||||||
socket.end();
|
for (const chunk of chunks) {
|
||||||
|
socket.write(chunk);
|
||||||
|
await new Promise<void>((resolve) => setTimeout(resolve, 5));
|
||||||
|
}
|
||||||
|
socket.end();
|
||||||
|
})();
|
||||||
});
|
});
|
||||||
socket.resume();
|
socket.resume();
|
||||||
});
|
});
|
||||||
@@ -105,6 +110,40 @@ describe('newline-framed broker test client', () => {
|
|||||||
expect(broker.connections()).toBe(1);
|
expect(broker.connections()).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('rejects trailing bytes delivered after a complete frame in a later data event', async () => {
|
||||||
|
const broker = await scriptedBroker([[Buffer.from('{"ok":true}\n'), Buffer.from('extra')]]);
|
||||||
|
|
||||||
|
const failure = await requestBrokerReply(broker.socketPath, { action: 'probe' }).catch(
|
||||||
|
(error: unknown) => error,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(failure).toBeInstanceOf(BrokerTransportError);
|
||||||
|
expect(failure).toMatchObject({ kind: 'malformed-reply', responseLength: 17 });
|
||||||
|
expect(failure).toHaveProperty(
|
||||||
|
'message',
|
||||||
|
expect.stringMatching(/bytes after the newline terminator/i),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('redacts security tokens from typed transport diagnostics', async () => {
|
||||||
|
const token = 'a'.repeat(64);
|
||||||
|
const reply = Buffer.from(`{"ok":true,"promotion_token":"${token}`);
|
||||||
|
const broker = await scriptedBroker([[reply]]);
|
||||||
|
|
||||||
|
const failure = await requestBrokerReply(broker.socketPath, { action: 'probe' }).catch(
|
||||||
|
(error: unknown) => error,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(failure).toBeInstanceOf(BrokerTransportError);
|
||||||
|
expect(failure).toMatchObject({
|
||||||
|
kind: 'early-close',
|
||||||
|
responseLength: reply.length,
|
||||||
|
responsePreview: '<redacted-sensitive-reply>',
|
||||||
|
});
|
||||||
|
expect(String((failure as Error).message)).not.toContain(token);
|
||||||
|
expect(JSON.stringify(failure)).not.toContain(token);
|
||||||
|
});
|
||||||
|
|
||||||
test.each([
|
test.each([
|
||||||
['trailing bytes', Buffer.from('{"ok":true}\nextra'), /bytes after the newline/i],
|
['trailing bytes', Buffer.from('{"ok":true}\nextra'), /bytes after the newline/i],
|
||||||
['non-object JSON', Buffer.from('[]\n'), /JSON value is not an object/i],
|
['non-object JSON', Buffer.from('[]\n'), /JSON value is not an object/i],
|
||||||
|
|||||||
Reference in New Issue
Block a user