test(#838): reject chunked garbage and redact tokens

This commit is contained in:
ms-lead-reviewer
2026-07-18 01:45:39 -05:00
parent be7ecbd63c
commit 6f0f8eecdc

View File

@@ -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],