Summary

Addresses #6403 — hosts on Shodan (and similar platforms) sometimes act as honeypots, returning responses that match many unrelated nuclei templates and producing noisy false positives. This PR adds per-host tracking of unique template matches with configurable threshold-based flagging.

/claim #6403

Changes

New package: pkg/honeypot

  • Detector struct — thread-safe, tracks unique template IDs per normalized host
  • NormalizeHost() — canonical host extraction from URLs, host:port, bare hostnames, IPv4/IPv6
  • RecordMatch(host, templateID) — registers a match; returns true when threshold is crossed
  • IsFlagged(host) / ShouldSuppress(host) — query flagged status
  • WarnOnce(host) — emits a single warning log per flagged host
  • PrintSummary() — end-of-scan summary of all flagged hosts
  • Memory cleanup — template tracking map is freed after a host is flagged (no unbounded growth)
  • Comprehensive test suite — 12 tests covering normalization (12 sub-cases), threshold logic, deduplication, suppression modes, concurrent access, memory cleanup, edge cases

Integration: pkg/output

  • StandardWriter gains a HoneypotDetector field
  • NewStandardWriter() initializes the detector when threshold > 0
  • Write() records every successful match and optionally suppresses output for flagged hosts
  • Close() prints the honeypot summary

CLI flags: cmd/nuclei/main.go + pkg/types

Flag Short Default Description
--honeypot-threshold -hpt 0 (disabled) Unique template match count before flagging
--honeypot-suppress -hpsu false Suppress results from flagged hosts

Usage

# Warn-only mode (default): flag honeypots but still show all results
nuclei -l targets.txt -t templates/ -honeypot-threshold 50
# Suppression mode: flag AND drop results from honeypot hosts
nuclei -l targets.txt -t templates/ -honeypot-threshold 50 -honeypot-suppress

Test Results

=== RUN TestNormalizeHost (12 sub-cases) --- PASS
=== RUN TestDetectorDisabled --- PASS
=== RUN TestDetectorNegativeThreshold --- PASS
=== RUN TestDetectorThresholdFlagging --- PASS
=== RUN TestDetectorSuppression --- PASS
=== RUN TestDetectorHostNormalizationConsistency --- PASS
=== RUN TestDetectorMultipleHosts --- PASS
=== RUN TestDetectorWarnOnce --- PASS
=== RUN TestDetectorConcurrency --- PASS
=== RUN TestDetectorMemoryCleanup --- PASS
=== RUN TestDetectorEmptyHost --- PASS
=== RUN TestDetectorMatchCountFlagged --- PASS
PASS 0.589s

Design Decisions

  1. Zero overhead when disabled — threshold=0 (default) means IsEnabled() returns false and all methods short-circuit immediately
  2. Deduplication — same template matching the same host multiple times doesn’t inflate the count
  3. Memory-efficient — after a host crosses the threshold, its template-ID set is deleted; only the flagged set is retained
  4. Warn-only by default — users see a warning but no results are dropped unless -honeypot-suppress is explicitly set
  5. Thread-safe — all Detector methods use a mutex, tested with 100 concurrent goroutines
  6. Host normalization — handles URLs with schemes, host:port, IPv4, IPv6 with brackets, mixed case

Summary by CodeRabbit

  • New Features

    • Added honeypot detection with configurable threshold and suppression via CLI flags.
    • Integrated detection into output flow to warn once per host, optionally suppressing results, and print a summary on shutdown.
  • Tests

    • Added comprehensive tests covering host normalization, thresholding, suppression, concurrency, and lifecycle behavior.

Claim

Total prize pool $250
Total paid $0
Status Pending
Submitted February 27, 2026
Last updated February 27, 2026

Contributors

TE

Tereda_Developer

@teredasites

100%

Sponsors

PR

ProjectDiscovery

@projectdiscovery

$250