From d4949d0c5aeedc22f07c5afc772ded83b2707a5f Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 24 Feb 2026 07:33:14 +0000 Subject: [PATCH] Flip verification overlap default: rename --allow-verification-overlap to --disallow-verification-overlap The verification overlap logic was enabled by default, causing non-deterministic scan results due to Go map iteration randomness in FindDetectorMatches feeding into the verificationOverlapWorker. The worker's detector processing order determined which detectors had results dropped vs preserved, leading to 2-5% count variance between runs on the same data. Additionally, the security control was only partially effective: it blocked N-1 of N overlapping detectors from verifying, but always let the first-encountered detector through -- and which detector was 'first' was random. This commit inverts the default so the overlap logic is OFF unless explicitly opted into via --disallow-verification-overlap. This makes scans deterministic by default and avoids the result-dropping behavior in the overlap worker. Co-authored-by: Dylan Ayrey --- main.go | 4 ++-- pkg/engine/engine.go | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/main.go b/main.go index bbe1b44e9..d2abe5f2f 100644 --- a/main.go +++ b/main.go @@ -61,7 +61,7 @@ var ( noColor = cli.Flag("no-color", "Disable colorized output").Bool() noColour = cli.Flag("no-colour", "Alias for --no-color").Hidden().Bool() - allowVerificationOverlap = cli.Flag("allow-verification-overlap", "Allow verification of similar credentials across detectors").Bool() + disallowVerificationOverlap = cli.Flag("disallow-verification-overlap", "Disallow verification of similar credentials across detectors. When set, secrets detected by multiple detectors will not be verified.").Bool() filterUnverified = cli.Flag("filter-unverified", "Only output first unverified result per chunk per detector if there are more than one results.").Bool() filterEntropy = cli.Flag("filter-entropy", "Filter unverified results with Shannon entropy. Start with 3.0.").Float64() scanEntireChunk = cli.Flag("scan-entire-chunk", "Scan the entire chunk for secrets.").Hidden().Default("false").Bool() @@ -559,7 +559,7 @@ func run(state overseer.State, logSync func() error) { Dispatcher: engine.NewPrinterDispatcher(printer), FilterUnverified: *filterUnverified, FilterEntropy: *filterEntropy, - VerificationOverlap: *allowVerificationOverlap, + DisableVerificationOverlap: *disallowVerificationOverlap, Results: parsedResults, PrintAvgDetectorTime: *printAvgDetectorTime, ShouldScanEntireChunk: *scanEntireChunk, diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index e45651dca..dfe4fddd0 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -39,7 +39,7 @@ var detectionTimeout = detectors.DefaultResponseTimeout var errOverlap = errors.New( "More than one detector has found this result. For your safety, verification has been disabled." + - "You can override this behavior by using the --allow-verification-overlap flag.", + " This behavior is enabled by the --disallow-verification-overlap flag.", ) // Metrics for the scan engine for external consumption. @@ -138,10 +138,10 @@ type Config struct { // and should be avoided unless specified by the user. PrintAvgDetectorTime bool - // VerificationOverlap determines whether the scanner will attempt to verify candidate secrets - // that have been detected by multiple detectors. - // By default, it is set to true. - VerificationOverlap bool + // DisableVerificationOverlap, when true, prevents verification of secrets that have been + // detected by multiple detectors. By default this is false, meaning all detectors are + // allowed to verify their findings independently. + DisableVerificationOverlap bool // DetectorWorkerMultiplier is used to determine the number of detector workers to spawn. DetectorWorkerMultiplier int @@ -184,9 +184,9 @@ type Engine struct { notifyVerifiedResults bool notifyUnverifiedResults bool notifyUnknownResults bool - retainFalsePositives bool - verificationOverlap bool - printAvgDetectorTime bool + retainFalsePositives bool + disableVerificationOverlap bool + printAvgDetectorTime bool // By default, the engine will only scan a subset of the chunk if a detector matches the chunk. // If this flag is set to true, the engine will scan the entire chunk. scanEntireChunk bool @@ -247,7 +247,7 @@ func NewEngine(ctx context.Context, cfg *Config) (*Engine, error) { filterEntropy: cfg.FilterEntropy, printAvgDetectorTime: cfg.PrintAvgDetectorTime, retainFalsePositives: cfg.LogFilteredUnverified, - verificationOverlap: cfg.VerificationOverlap, + disableVerificationOverlap: cfg.DisableVerificationOverlap, sourceManager: cfg.SourceManager, scanEntireChunk: cfg.ShouldScanEntireChunk, detectorVerificationOverrides: cfg.DetectorVerificationOverrides, @@ -857,7 +857,7 @@ func (e *Engine) scannerWorker(ctx context.Context) { for _, d := range decoded { matchingDetectors := e.AhoCorasickCore.FindDetectorMatches(d.Chunk.Data) - if len(matchingDetectors) > 1 && !e.verificationOverlap { + if len(matchingDetectors) > 1 && e.disableVerificationOverlap { wgVerificationOverlap.Add(1) e.verificationOverlapChunksChan <- verificationOverlapChunk{ chunk: *d.Chunk,