diff --git a/.csreview-ignore b/.csreview-ignore new file mode 100644 index 0000000..b9de80d --- /dev/null +++ b/.csreview-ignore @@ -0,0 +1,10 @@ +# CSReview self-scan hygiene (read-only; report-level suppression). +# +# Mirrors csreview/.csreview-ignore so a self-audit is clean whether the scan root +# is the repo root or the package dir. These files DEFINE the security rules and +# remediation content (regex literals, rule names, descriptions, exploitation +# examples, the DB-dump guide's sample connection strings); the heuristic detector +# matches its own definitions when scanning csreview itself. Logic bugs are still +# covered by Semgrep + CodeQL in CI. +**/src/detector.js +**/src/dumpGuide.js diff --git a/csreview/.csreview-ignore b/csreview/.csreview-ignore new file mode 100644 index 0000000..f387caf --- /dev/null +++ b/csreview/.csreview-ignore @@ -0,0 +1,13 @@ +# CSReview self-scan hygiene (read-only; report-level suppression). +# +# These files DEFINE the security rules and remediation content: regex literals, +# rule names, descriptions, exploitation examples, and the DB-dump guide's sample +# connection strings. When CSReview audits its OWN source, the heuristic detector +# matches its own definitions — a scanner flagging its own rulebook. That noise is +# specific to scanning csreview itself and never occurs in a user's project. Logic +# bugs in these files are still covered by Semgrep + CodeQL in CI. +# +# `**/`-prefixed so it works whether the scan root is the package dir (src/...) or +# the repo root (csreview/src/...). +**/src/detector.js +**/src/dumpGuide.js diff --git a/csreview/test/detector-calibration.test.js b/csreview/test/detector-calibration.test.js index 1556f94..02ee99d 100644 --- a/csreview/test/detector-calibration.test.js +++ b/csreview/test/detector-calibration.test.js @@ -4,7 +4,9 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; +import { fileURLToPath } from 'node:url'; import { detectVulnerabilities } from '../src/detector.js'; +import { runAnalysis } from '../src/index.js'; // Calibration guards driven by real user feedback: the internal detector was // "shouting fire because it saw the word match in the dictionary" — WEAK_CIPHER @@ -84,3 +86,20 @@ test('findings in non-source paths (test/fixtures) are downgraded; real source k assert.equal(inTest.severity, 'LOW', 'test/fixture finding is downgraded to LOW'); assert.equal(inTest.confidence, 'LOW'); }); + +test('the shipped .csreview-ignore keeps a csreview self-audit free of rule-definition meta-FPs', async () => { + // A scanner must not flag its own rulebook: detector.js (regexes/descriptions/ + // exploitation strings) and dumpGuide.js (sample connection strings) match the + // detector's own definitions only when csreview audits itself. The shipped + // .csreview-ignore suppresses them. (Reported by Thiago via GPT.) + const pkgRoot = fileURLToPath(new URL('..', import.meta.url)); + const out = fs.mkdtempSync(path.join(os.tmpdir(), 'csreview-selfscan-')); + const result = await runAnalysis(pkgRoot, { outputDir: out, runTools: false }); + const ruleDefHits = result.findings.filter((f) => /src[\\/](?:detector|dumpGuide)\.js/.test(String(f.file))); + assert.equal( + ruleDefHits.length, + 0, + `rule-definition files must be suppressed, got: ${ruleDefHits.map((f) => `${f.file}:${f.line}`).join(', ')}`, + ); + assert.ok(result.suppressedByIgnore > 0, 'expected the .csreview-ignore to suppress the rule-definition meta-FPs'); +});