From daef71c74c44689490ce2808dfadb515496db252 Mon Sep 17 00:00:00 2001 From: dev-ecd-dm Date: Wed, 3 Jun 2026 17:08:10 -0300 Subject: [PATCH] fix(detector): ship .csreview-ignore so a self-audit skips csreview's own rulebook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to the detector calibration (#17). User feedback (Thiago via GPT): the remaining false positives were in src/detector.js itself — the heuristic detector matching its OWN rule definitions (regex literals, rule names, descriptions, exploitation examples) plus dumpGuide.js's sample connection strings. This only happens when csreview audits its own source; it never occurs in user projects. - Ship .csreview-ignore (repo root + package dir) excluding src/detector.js and src/dumpGuide.js from the report — report-level, read-only suppression via the existing ignore mechanism. `**/`-prefixed so it works from either scan root. - Logic bugs in those files remain covered by Semgrep + CodeQL in CI. - Test: a self-audit (runAnalysis, runTools:false) now yields zero findings in the rule-definition files and records them under suppressedByIgnore. 176/176 - lint clean - typecheck 0. Co-Authored-By: Claude Opus 4.8 (1M context) --- .csreview-ignore | 10 ++++++++++ csreview/.csreview-ignore | 13 +++++++++++++ csreview/test/detector-calibration.test.js | 19 +++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 .csreview-ignore create mode 100644 csreview/.csreview-ignore 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'); +});