Files
gstack/test/audit-compliance.test.ts
T
Garry Tan 11695e3aca fix: security audit compliance — credentials, telemetry, bun pin, untrusted warning (v0.12.12.0) (#574)
* fix: replace hardcoded credentials with env vars in documentation

Addresses Snyk W007 (HIGH). Replaces test@example.com/password123 with
$TEST_EMAIL/$TEST_PASSWORD env vars. Adds credential safety and cookie
safety notes.

* fix: make telemetry binary calls conditional on _TEL and binary existence

Addresses Socket's 14 MEDIUM findings for opaque telemetry binary.
Adds local JSONL fallback (always available, inspectable). Remote
binary only runs if _TEL != "off" and binary exists.

* fix: pin bun install to v1.3.10 with existence check

Addresses Snyk W012 (MEDIUM). Pins BUN_VERSION in browse.ts resolver,
Dockerfile.ci, and setup script error message. Adds command -v check
to skip install if bun already present.

* docs: add data flow documentation to review.ts

Addresses Socket HIGH finding (98% confidence). Documents what data
is sent to external review services and what is NOT sent.

* test: add audit compliance regression tests

6 tests enforce Snyk/Socket fixes stay in place: no hardcoded creds,
conditional telemetry, version-pinned bun, untrusted content warning,
data flow docs, all SKILL.md telemetry conditional.

* refactor: remove 2017 lines of dead code from gen-skill-docs.ts

The Placeholder Resolvers section (lines 77-2092) contained duplicate
functions that were superseded by scripts/resolvers/*.ts. The RESOLVERS
map from resolvers/index.ts is the sole resolution path. Verified: zero
call sites outside self-references.

* chore: regenerate SKILL.md files from updated templates

Reflects: conditional telemetry, version-pinned bun install,
untrusted content warning after Navigation commands.

* chore: bump version and changelog (v0.12.12.0)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 12:06:58 -06:00

89 lines
3.9 KiB
TypeScript

import { describe, test, expect } from 'bun:test';
import { readFileSync, readdirSync, existsSync } from 'fs';
import { join } from 'path';
const ROOT = join(import.meta.dir, '..');
function getAllSkillMds(): Array<{ name: string; content: string }> {
const results: Array<{ name: string; content: string }> = [];
const rootPath = join(ROOT, 'SKILL.md');
if (existsSync(rootPath)) {
results.push({ name: 'root', content: readFileSync(rootPath, 'utf-8') });
}
for (const entry of readdirSync(ROOT, { withFileTypes: true })) {
if (!entry.isDirectory() || entry.name.startsWith('.') || entry.name === 'node_modules') continue;
const skillPath = join(ROOT, entry.name, 'SKILL.md');
if (existsSync(skillPath)) {
results.push({ name: entry.name, content: readFileSync(skillPath, 'utf-8') });
}
}
return results;
}
describe('Audit compliance', () => {
// Fix 1: W007 — No hardcoded credentials in documentation
test('no hardcoded credential patterns in SKILL.md.tmpl', () => {
const tmpl = readFileSync(join(ROOT, 'SKILL.md.tmpl'), 'utf-8');
expect(tmpl).not.toContain('"password123"');
expect(tmpl).not.toContain('"test@example.com"');
expect(tmpl).not.toContain('"test@test.com"');
expect(tmpl).toContain('$TEST_EMAIL');
expect(tmpl).toContain('$TEST_PASSWORD');
});
// Fix 2: Conditional telemetry — binary calls wrapped with existence check
test('preamble telemetry calls are conditional on _TEL and binary existence', () => {
const preamble = readFileSync(join(ROOT, 'scripts/resolvers/preamble.ts'), 'utf-8');
// Pending finalization must check _TEL and binary existence
expect(preamble).toContain('_TEL" != "off"');
expect(preamble).toContain('-x ');
expect(preamble).toContain('gstack-telemetry-log');
// End-of-skill telemetry must also be conditional
const completionIdx = preamble.indexOf('Telemetry (run last)');
expect(completionIdx).toBeGreaterThan(-1);
const completionSection = preamble.slice(completionIdx);
expect(completionSection).toContain('_TEL" != "off"');
});
// Fix 3: W012 — Bun install is version-pinned
test('bun install commands use version pinning', () => {
const browseResolver = readFileSync(join(ROOT, 'scripts/resolvers/browse.ts'), 'utf-8');
expect(browseResolver).toContain('BUN_VERSION');
// Should not have unpinned curl|bash (without BUN_VERSION on same line)
const lines = browseResolver.split('\n');
for (const line of lines) {
if (line.includes('bun.sh/install') && line.includes('bash') && !line.includes('BUN_VERSION') && !line.includes('command -v')) {
throw new Error(`Unpinned bun install found: ${line.trim()}`);
}
}
});
// Fix 4: W011 — Untrusted content warning in command reference
test('command reference includes untrusted content warning after Navigation', () => {
const rootSkill = readFileSync(join(ROOT, 'SKILL.md'), 'utf-8');
const navIdx = rootSkill.indexOf('### Navigation');
const readingIdx = rootSkill.indexOf('### Reading');
expect(navIdx).toBeGreaterThan(-1);
expect(readingIdx).toBeGreaterThan(navIdx);
const between = rootSkill.slice(navIdx, readingIdx);
expect(between.toLowerCase()).toContain('untrusted');
});
// Fix 5: Data flow documentation in review.ts
test('review.ts has data flow documentation', () => {
const review = readFileSync(join(ROOT, 'scripts/resolvers/review.ts'), 'utf-8');
expect(review).toContain('Data sent');
expect(review).toContain('Data NOT sent');
});
// Fix 2+6: All generated SKILL.md files with telemetry are conditional
test('all generated SKILL.md files with telemetry calls use conditional pattern', () => {
const skills = getAllSkillMds();
for (const { name, content } of skills) {
if (content.includes('gstack-telemetry-log')) {
expect(content).toContain('_TEL" != "off"');
}
}
});
});