From 1c2d5dd389d6b597718f28dc777e33525e0fe3fd Mon Sep 17 00:00:00 2001 From: Affaan Mustafa Date: Wed, 29 Apr 2026 18:03:33 -0400 Subject: [PATCH] fix: fail open on insaits monitor errors --- scripts/hooks/insaits-security-wrapper.js | 10 +++++++ tests/hooks/insaits-security-wrapper.test.js | 28 +++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/scripts/hooks/insaits-security-wrapper.js b/scripts/hooks/insaits-security-wrapper.js index 710d9be8..7010c0f6 100644 --- a/scripts/hooks/insaits-security-wrapper.js +++ b/scripts/hooks/insaits-security-wrapper.js @@ -98,6 +98,16 @@ process.stdin.on('end', () => { process.exit(0); } + // The monitor only uses 0 (pass) and 2 (block). Other statuses usually + // mean Python launcher/dependency/runtime failure, so keep the hook fail-open. + if (result.status !== 0 && result.status !== 2) { + const detail = (result.stderr || result.stdout || '').trim(); + const suffix = detail ? `: ${detail}` : ''; + process.stderr.write(`[InsAIts] Security monitor exited with status ${result.status}${suffix}\n`); + process.stdout.write(raw); + process.exit(0); + } + if (result.stdout) { process.stdout.write(result.stdout); } else if (result.status === 0) { diff --git a/tests/hooks/insaits-security-wrapper.test.js b/tests/hooks/insaits-security-wrapper.test.js index 4d5c3401..17b5a4b0 100644 --- a/tests/hooks/insaits-security-wrapper.test.js +++ b/tests/hooks/insaits-security-wrapper.test.js @@ -166,6 +166,29 @@ function runTests() { } })) passed++; else failed++; + if (test('enabled monitor unexpected failure fails open with warning and raw stdin', () => { + const tempDir = createTempDir(); + try { + writeFakePython(path.join(tempDir, 'bin')); + + const result = run({ + input: 'raw-input', + env: { + ECC_ENABLE_INSAITS: '1', + FAKE_INSAITS_MODE: 'error', + PATH: path.join(tempDir, 'bin'), + }, + }); + + assert.strictEqual(result.status, 0); + assert.strictEqual(result.stdout, 'raw-input'); + assert.ok(result.stderr.includes('Security monitor exited with status 1')); + assert.ok(result.stderr.includes('spawned but failed')); + } finally { + cleanup(tempDir); + } + })) passed++; else failed++; + if (test('missing Python fails open with warning and raw stdin', () => { const result = run({ input: 'raw-input', @@ -177,7 +200,10 @@ function runTests() { assert.strictEqual(result.status, 0); assert.strictEqual(result.stdout, 'raw-input'); - assert.ok(result.stderr.includes('python3/python not found')); + assert.ok( + result.stderr.includes('python3/python not found') + || result.stderr.includes('Security monitor exited with status') + ); })) passed++; else failed++; console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`);