Protect RCON diagnostics and redact player addresses (Refs #61)
This commit is contained in:
+33
-1
@@ -4,8 +4,40 @@ import {
|
||||
parsePlayerCount,
|
||||
parsePlayerRoster,
|
||||
parseStatusHeader,
|
||||
formatRawReply
|
||||
formatRawReply,
|
||||
agentRconStatusResult
|
||||
} from '../../src/lib/server/integrations/rcon.js';
|
||||
import { redactRconAddresses } from '../../src/lib/server/integrations/rcon-diagnostics.js';
|
||||
|
||||
describe('private RCON diagnostics', () => {
|
||||
const addresses = ['192.0.2.123:28960', '198.51.100.9', '[2001:db8::1]:28960',
|
||||
'2001:db8::abcd', '[::ffff:192.0.2.4]:28960', '[fe80::1%eth0]:1234', '::1'];
|
||||
|
||||
it.each(addresses)('redacts %s from both plain text and decoded hex diagnostics', address => {
|
||||
const text = `unrecognized status\nplayer address ${address} trailing text`;
|
||||
expect(redactRconAddresses(text)).toBe('unrecognized status\nplayer address [redacted] trailing text');
|
||||
const dump = formatRawReply(Buffer.from(text));
|
||||
const hex = dump.split('\n').map(line => line.slice(6, 53).trim()).join(' ').replaceAll(' ', '');
|
||||
const decoded = Buffer.from(hex, 'hex').toString();
|
||||
expect(decoded).toBe(redactRconAddresses(text));
|
||||
});
|
||||
|
||||
it('redacts complete addresses before truncating native and UDP replies', () => {
|
||||
const native = agentRconStatusResult({ text: 'x'.repeat(3990) + ' 192.0.2.123:28960' }, { host: 'agent', port: 1 });
|
||||
expect(native).toMatchObject({ ok: false });
|
||||
expect(native.rawReply).not.toContain('192.0.2');
|
||||
expect(native.rawReply!.length).toBeLessThanOrEqual(4000);
|
||||
const dump = formatRawReply(Buffer.from('x'.repeat(500) + ' 192.0.2.123:28960'));
|
||||
const hex = dump.split('\n').filter(line => /^[0-9a-f]{4} /.test(line)).map(line => line.slice(6, 53).trim()).join(' ').replaceAll(' ', '');
|
||||
expect(Buffer.from(hex, 'hex').toString()).not.toContain('192.0.2');
|
||||
});
|
||||
|
||||
it('omits native success replies while preserving the parsed status', () => {
|
||||
const result = agentRconStatusResult({ text: 'print\nmap: mp_kino\nnum score ping guid name address\n--- ----- ---- ---- ---- -------\n' }, { host: 'agent', port: 1 });
|
||||
expect(result).toMatchObject({ ok: true, status: { players: 0, map: 'mp_kino' } });
|
||||
expect(result).not.toHaveProperty('rawReply');
|
||||
});
|
||||
});
|
||||
|
||||
describe('parsePlayerCount', () => {
|
||||
it('counts rows after --- --- separator (status dialect)', () => {
|
||||
|
||||
Reference in New Issue
Block a user