'use strict'; const test = require('node:test'); const assert = require('node:assert/strict'); const { EventEmitter } = require('node:events'); const fs = require('node:fs'); const path = require('node:path'); const MODULE_PATH = '../src/proxy-launch'; const APPROVED_DIRECTORY = 'C:\\Program Files\\Alta Proxy Tool'; const APPROVED_HELPER = 'C:\\Program Files\\Alta Proxy Tool\\aware-cam-proxy.exe'; const VALID_HOST = 'tenant.avasecurity.com'; const VALID_DEVICE_ID = '123e4567-e89b-42d3-a456-426614174000'; const SYNTHETIC_COOKIE = 'HERMES_SENTINEL_SESSION_COOKIE'; function loadModule() { return require(MODULE_PATH); } class FakeChild extends EventEmitter { constructor(pid, killResult = true) { super(); this.pid = pid; this.killResult = killResult; this.killCalls = []; this.killError = null; this.exitCode = null; this.signalCode = null; } kill(signal) { this.killCalls.push(signal); if (this.killError) throw this.killError; return this.killResult; } } function createHarness({ helperExists = true, children = [new FakeChild(4101)], stopTimeoutMs = 5_000, setTimeout = global.setTimeout, clearTimeout = global.clearTimeout, } = {}) { const calls = []; let childIndex = 0; const spawn = (...args) => { calls.push(args); return children[childIndex++]; }; const fsStub = { existsSync: (candidate) => helperExists && candidate === APPROVED_HELPER }; const { createProxyManager } = loadModule(); const manager = createProxyManager({ appDirectory: APPROVED_DIRECTORY, fs: fsStub, spawn, platform: 'win32', now: () => 1_777_777_777_777, stopTimeoutMs, setTimeout, clearTimeout, }); return { manager, calls, children }; } function validRequest(overrides = {}) { return { deploymentHost: VALID_HOST, deviceId: VALID_DEVICE_ID, cookie: SYNTHETIC_COOKIE, ...overrides }; } test('exports the proxy manager module', () => { assert.doesNotThrow(() => loadModule()); }); test('launches the approved helper directly with the paired Alta session', () => { const { manager, calls } = createHarness(); const result = manager.launchProxy(validRequest()); assert.deepEqual(calls, [[ APPROVED_HELPER, ['-a', VALID_HOST, '-d', VALID_DEVICE_ID, '-k', SYNTHETIC_COOKIE], { shell: false, detached: true, stdio: 'ignore', windowsHide: false } ]]); assert.deepEqual(result, { success: true, processId: 4101, deviceId: VALID_DEVICE_ID, startedAt: 1_777_777_777_777, status: 'running' }); }); test('passes the paired cookie literally without invoking a shell or console prompt', () => { const cookie = 'abc_DEF-123.456=='; const { manager, calls } = createHarness(); manager.launchProxy(validRequest({ cookie })); assert.equal(calls[0][1][5], cookie); assert.equal(calls[0][2].shell, false); assert.equal(calls[0][2].stdio, 'ignore'); }); test('rejects the CRLF calc.exe reproducer in every structured input', () => { const { manager, calls } = createHarness(); const attacks = [ { deploymentHost: `${VALID_HOST}\r\ncalc.exe` }, { deviceId: `${VALID_DEVICE_ID}\r\ncalc.exe` }, { cookie: `${SYNTHETIC_COOKIE}\r\ncalc.exe` }, { cookie: `${SYNTHETIC_COOKIE}\0calc.exe` } ]; for (const attack of attacks) { assert.throws(() => manager.launchProxy(validRequest(attack)), /invalid|must not contain/i); } assert.equal(calls.length, 0); }); test('rejects shell metacharacters in deployment hosts and device identifiers', () => { const { manager, calls } = createHarness(); for (const deploymentHost of [ 'tenant.avasecurity.com&calc.exe', 'tenant.avasecurity.com|calc.exe', 'https://tenant.avasecurity.com', 'tenant.avasecurity.com/path', 'tenant.avasecurity.com:443' ]) { assert.throws(() => manager.launchProxy(validRequest({ deploymentHost })), /deployment host/i); } for (const deviceId of [ `${VALID_DEVICE_ID}&calc.exe`, `${VALID_DEVICE_ID}|calc.exe`, '$(calc.exe)' ]) { assert.throws(() => manager.launchProxy(validRequest({ deviceId })), /device identifier/i); } assert.equal(calls.length, 0); }); test('accepts only strict canonical UUID device identifiers', () => { const invalidIds = [ '', '123e4567-e89b-12d3-a456-42661417400', '123e4567e89b42d3a456426614174000', '123e4567-e89b-02d3-a456-426614174000', '123e4567-e89b-42d3-c456-426614174000', 'g23e4567-e89b-42d3-a456-426614174000', 'a'.repeat(37) ]; for (const deviceId of invalidIds) { const { manager } = createHarness(); assert.throws(() => manager.launchProxy(validRequest({ deviceId })), /device identifier/i); } }); test('accepts only bounded Alta subdomain hostnames from trusted session state', () => { const invalidHosts = [ '', 'avasecurity.com', 'avigilon.com', 'evil.example', 'tenant.avasecurity.com.evil.example', '.avasecurity.com', '-tenant.avasecurity.com', 'tenant..avasecurity.com', 'tenant_avasecurity.com', `tenant.${'a'.repeat(240)}.avasecurity.com` ]; for (const deploymentHost of invalidHosts) { const { manager } = createHarness(); assert.throws(() => manager.launchProxy(validRequest({ deploymentHost })), /deployment host/i); } }); test('normalizes a valid Alta hostname to lowercase', () => { const { manager, calls } = createHarness(); manager.launchProxy(validRequest({ deploymentHost: 'Tenant.AVIGILON.com' })); assert.equal(calls[0][1][1], 'tenant.avigilon.com'); }); test('rejects empty, oversized, non-string, and control-character cookies', () => { for (const cookie of ['', 'x'.repeat(4097), 42, 'abc\nxyz', 'abc\rxyz', 'abc\0xyz', 'abc;xyz']) { const { manager } = createHarness(); assert.throws(() => manager.launchProxy(validRequest({ cookie })), /cookie/i); } }); test('fails closed when the fixed helper is missing and never spawns', () => { const { manager, calls } = createHarness({ helperExists: false }); assert.throws(() => manager.launchProxy(validRequest()), /helper.*not found/i); assert.equal(calls.length, 0); }); test('requires an absolute approved application directory and Windows platform', () => { const { createProxyManager } = loadModule(); const dependencies = { fs: { existsSync: () => true }, spawn: () => new FakeChild(1) }; assert.throws( () => createProxyManager({ appDirectory: '..\\untrusted', platform: 'win32', ...dependencies }), /absolute/i ); assert.throws( () => createProxyManager({ appDirectory: '/opt/apt', platform: 'linux', ...dependencies }), /platform/i ); }); test('redacts the cookie if spawn throws an error containing it', () => { const { createProxyManager } = loadModule(); const manager = createProxyManager({ appDirectory: APPROVED_DIRECTORY, fs: { existsSync: () => true }, platform: 'win32', spawn: () => { throw new Error(`spawn failed for ${SYNTHETIC_COOKIE}`); } }); assert.throws( () => manager.launchProxy(validRequest()), (error) => { assert.match(error.message, /spawn failed/); assert.match(error.message, /\[REDACTED\]/); assert.doesNotMatch(error.message, /HERMES_SENTINEL_SESSION_COOKIE/); return true; } ); }); test('tracks only safe process metadata and never exposes cookies', () => { const { manager } = createHarness(); manager.launchProxy(validRequest()); const tracked = manager.listTrackedProxies(); assert.deepEqual(tracked, [{ processId: 4101, deviceId: VALID_DEVICE_ID, startedAt: 1_777_777_777_777, status: 'running' }]); assert.doesNotMatch(JSON.stringify(tracked), /HERMES_SENTINEL_SESSION_COOKIE/); }); test('stopping one tracked process waits for confirmed exit and leaves the other alive', async () => { const first = new FakeChild(4101); const second = new FakeChild(4102); const { manager } = createHarness({ children: [first, second] }); manager.launchProxy(validRequest()); manager.launchProxy(validRequest({ deviceId: '123e4567-e89b-42d3-a456-426614174001' })); const stopping = manager.stopProxy(4101); assert.deepEqual(manager.listTrackedProxies().map((item) => [item.processId, item.status]), [ [4101, 'stopping'], [4102, 'running'], ]); first.emit('exit', 0, 'SIGTERM'); const result = await stopping; assert.deepEqual(result, { success: true, processId: 4101, deviceId: VALID_DEVICE_ID, status: 'stopped' }); assert.deepEqual(first.killCalls, ['SIGTERM']); assert.deepEqual(second.killCalls, []); assert.deepEqual(manager.listTrackedProxies().map((item) => item.processId), [4102]); }); test('never stops an untracked PID', async () => { const child = new FakeChild(4101); const { manager } = createHarness({ children: [child] }); manager.launchProxy(validRequest()); assert.deepEqual(await manager.stopProxy(9999), { success: false, processId: 9999, status: 'not-tracked' }); assert.deepEqual(child.killCalls, []); }); test('reports already-exited and permission-denied states honestly', async () => { const exited = new FakeChild(4101, false); exited.exitCode = 0; const denied = new FakeChild(4102); denied.killError = Object.assign(new Error('operation not permitted'), { code: 'EPERM' }); const { manager } = createHarness({ children: [exited, denied] }); manager.launchProxy(validRequest()); manager.launchProxy(validRequest({ deviceId: '123e4567-e89b-42d3-a456-426614174001' })); assert.deepEqual(await manager.stopProxy(4101), { success: true, processId: 4101, deviceId: VALID_DEVICE_ID, status: 'already-exited' }); assert.deepEqual(await manager.stopProxy(4102), { success: false, processId: 4102, deviceId: '123e4567-e89b-42d3-a456-426614174001', status: 'permission-denied', message: 'Unable to stop the tracked proxy process: permission denied.' }); assert.deepEqual(manager.listTrackedProxies().map((item) => item.processId), [4102]); }); test('kill true is only a request and times out while the child remains tracked as stopping', async () => { let timeoutCallback; const child = new FakeChild(4101, true); const { manager } = createHarness({ children: [child], stopTimeoutMs: 25, setTimeout(callback, delay) { assert.equal(delay, 25); timeoutCallback = callback; return 123; }, clearTimeout() {}, }); manager.launchProxy(validRequest()); const stopping = manager.stopProxy(4101); assert.deepEqual(manager.listTrackedProxies().map(({ processId, status }) => ({ processId, status })), [ { processId: 4101, status: 'stopping' }, ]); timeoutCallback(); assert.deepEqual(await stopping, { success: false, processId: 4101, deviceId: VALID_DEVICE_ID, status: 'stop-timeout', message: 'Timed out waiting for the tracked proxy process to exit.', }); assert.equal(manager.listTrackedProxies()[0].status, 'stopping'); }); test('kill false does not claim success without confirmed exit', async () => { const child = new FakeChild(4101, false); const { manager } = createHarness({ children: [child] }); manager.launchProxy(validRequest()); assert.deepEqual(await manager.stopProxy(4101), { success: false, processId: 4101, deviceId: VALID_DEVICE_ID, status: 'stop-failed', message: 'Unable to confirm that the tracked proxy process exited.', }); assert.equal(manager.listTrackedProxies()[0].status, 'stopping'); }); test('generic child errors retain tracking unless process exit is confirmed', () => { const child = new FakeChild(4101); const { manager } = createHarness({ children: [child] }); manager.launchProxy(validRequest()); child.emit('error', new Error('transient process error')); assert.deepEqual(manager.listTrackedProxies().map((entry) => entry.processId), [4101]); }); test('exit events remove only the matching owned child', () => { const original = new FakeChild(4101); const replacement = new FakeChild(4101); const { manager } = createHarness({ children: [original, replacement] }); manager.launchProxy(validRequest()); original.emit('exit', 0); manager.launchProxy(validRequest({ deviceId: '123e4567-e89b-42d3-a456-426614174001' })); original.emit('exit', 0); assert.deepEqual(manager.listTrackedProxies().map((item) => item.processId), [4101]); }); test('source contains no shell launchers, broad process killers, or credential persistence APIs', () => { const source = fs.readFileSync(path.join(__dirname, '..', 'src', 'proxy-launch.js'), 'utf8'); assert.doesNotMatch(source, /\b(?:cmd(?:\.exe)?|powershell|taskkill|pkill|wmic)\b/i); assert.doesNotMatch(source, /\.(?:bat|command)\b/i); assert.doesNotMatch(source, /(?:writeFile|appendFile|mkdtemp|tmpdir)/); assert.match(source, /shell:\s*false/); });