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 <[email protected]>
This commit is contained in:
Cursor Agent
2026-02-24 07:33:14 +00:00
co-authored by Dylan Ayrey
parent be889fa341
commit d4949d0c5a
2 changed files with 12 additions and 12 deletions
+2 -2
View File
@@ -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,
+10 -10
View File
@@ -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,