mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-14 17:05:28 +02:00
fix: pre-landing review fixes
Review army findings (1 critical, auto-fixed with regression tests):
- CRITICAL (security specialist, verified live): redactFindingSpans spliced
only the regex capture span, and pem.private_key / gcp.service_account
capture just the BEGIN-header — the key body survived "redaction" and
shipped via telemetry. Marker-only patterns now drop the whole payload
(null, fail closed). Overlapping spans (Bearer+JWT on the same bytes) are
coalesced before splicing so stale offsets can't leave partial secret
bytes behind.
- gitStrict: drop the dead `|| r.status === null` disjunct (null !== 0
already covers it); add the signal-kill/null-status regression test the
docstring promised.
- security-dashboard human mode flags stale snapshots ("figures may be out
of date") instead of presenting frozen counts as current.
- community-dashboard marker check uses jq when available — the grep-only
variant misclassified whitespaced/reserialized bodies as legacy.
- telemetry fail-closed test now shadows bun with a failing stub
(deterministic on any host layout); stale "five status cases" describe
title renamed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
88ca684929
commit
8c8e3b9e52
+30
-6
@@ -222,12 +222,21 @@ describe('gstack-telemetry-log', () => {
|
||||
test('fails closed: error_message becomes null when the redactor is unavailable (#1947)', () => {
|
||||
setConfig('telemetry', 'anonymous');
|
||||
const token = 'ghp_' + 'A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8';
|
||||
// PATH without bun: the redaction snippet cannot run, so the whole
|
||||
// message must drop — never raw passthrough.
|
||||
run(
|
||||
`${BIN}/gstack-telemetry-log --skill qa --duration 10 --outcome error --error-message 'auth ${token} rejected' --session-id red-2`,
|
||||
{ PATH: '/usr/bin:/bin' },
|
||||
);
|
||||
// Shadow bun with a failing stub on a prepended PATH (deterministic on
|
||||
// any host layout — pre-landing review flagged the bare '/usr/bin:/bin'
|
||||
// variant as environment-dependent): the redaction snippet cannot run,
|
||||
// so the whole message must drop — never raw passthrough.
|
||||
const stubBin = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-tel-nobun-'));
|
||||
try {
|
||||
fs.writeFileSync(path.join(stubBin, 'bun'), '#!/bin/sh\nexit 127\n');
|
||||
fs.chmodSync(path.join(stubBin, 'bun'), 0o755);
|
||||
run(
|
||||
`${BIN}/gstack-telemetry-log --skill qa --duration 10 --outcome error --error-message 'auth ${token} rejected' --session-id red-2`,
|
||||
{ PATH: `${stubBin}:${process.env.PATH}` },
|
||||
);
|
||||
} finally {
|
||||
fs.rmSync(stubBin, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
const lines = readJsonl();
|
||||
expect(lines).toHaveLength(1);
|
||||
@@ -236,6 +245,21 @@ describe('gstack-telemetry-log', () => {
|
||||
expect(lines[0]).not.toContain(token);
|
||||
});
|
||||
|
||||
test('fails closed: PEM key in error_message drops the whole message (#1947 review fix)', () => {
|
||||
setConfig('telemetry', 'anonymous');
|
||||
// Header-only pattern: span replacement would forward the key body, so
|
||||
// the engine returns null and the bin must store null.
|
||||
run(
|
||||
`${BIN}/gstack-telemetry-log --skill qa --duration 10 --outcome error --error-message 'deploy failed: -----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASC' --session-id red-5`,
|
||||
);
|
||||
|
||||
const lines = readJsonl();
|
||||
expect(lines).toHaveLength(1);
|
||||
const event = JSON.parse(lines[0]);
|
||||
expect(event.error_message).toBeNull();
|
||||
expect(lines[0]).not.toContain('MIIEvQIBADAN');
|
||||
});
|
||||
|
||||
test('truncates error_message to 200 chars after redaction (#1947)', () => {
|
||||
setConfig('telemetry', 'anonymous');
|
||||
const long = 'x'.repeat(300);
|
||||
|
||||
Reference in New Issue
Block a user