Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
dnsx
cmd/dnsx/dnsx
.DS_Store
dist/
Expand Down
32 changes: 16 additions & 16 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ require (
github.com/miekg/dns v1.1.62
github.com/pkg/errors v0.9.1
github.com/projectdiscovery/asnmap v1.1.1
github.com/projectdiscovery/cdncheck v1.2.13
github.com/projectdiscovery/cdncheck v1.1.36
github.com/projectdiscovery/clistats v0.1.1
github.com/projectdiscovery/goconfig v0.0.1
github.com/projectdiscovery/goflags v0.1.74
github.com/projectdiscovery/gologger v1.1.62
github.com/projectdiscovery/hmap v0.0.98
github.com/projectdiscovery/mapcidr v1.1.97
github.com/projectdiscovery/ratelimit v0.0.82
github.com/projectdiscovery/retryabledns v1.0.111
github.com/projectdiscovery/utils v0.7.3
github.com/projectdiscovery/gologger v1.1.56
github.com/projectdiscovery/hmap v0.0.90
github.com/projectdiscovery/mapcidr v1.1.34
github.com/projectdiscovery/ratelimit v0.0.81
github.com/projectdiscovery/retryabledns v1.0.102
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check retryabledns Options struct and NewWithOptions in v1.0.102

echo "=== Cloning retryabledns v1.0.102 ==="
git clone --depth 1 --branch v1.0.102 https://github.com/projectdiscovery/retryabledns /tmp/retryabledns-v1.0.102 2>/dev/null

if [ -d /tmp/retryabledns-v1.0.102 ]; then
  echo ""
  echo "Checking Options struct fields:"
  rg -A 20 'type Options struct' /tmp/retryabledns-v1.0.102
  
  echo ""
  echo "Checking NewWithOptions function signature:"
  rg -B 2 -A 5 'func NewWithOptions' /tmp/retryabledns-v1.0.102
  
  rm -rf /tmp/retryabledns-v1.0.102
fi

Repository: projectdiscovery/dnsx

Length of output: 4247


Investigate why retryabledns was downgraded from v1.0.111 to v1.0.102.

The downgrade spans 9 patch versions, which could revert bug fixes. API compatibility has been confirmed—v1.0.102 includes all required Options struct fields (BaseResolvers, MaxRetries, Hostsfile, Proxy, Timeout) and the NewWithOptions() function signature. However, the downgrade itself is unusual and suggests either a regression in v1.0.103+ or a workaround. Clarify the reason for this change to avoid introducing unforeseen issues or technical debt.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@go.mod` at line 20, Review the commit or dependency changes that replaced
github.com/projectdiscovery/retryabledns v1.0.111 with v1.0.102: check the
go.sum/history/replace directives, module upgrades in nearby commits, and
CI/build logs for errors; verify differences between v1.0.111 and v1.0.102 by
inspecting the upstream changelog/commit history for retryabledns and confirm
any behavioral/regression reasons for pinning, focusing on the Options struct
and NewWithOptions() API, and then either restore the newer version (v1.0.111+)
if safe or add a concise comment/PR note explaining the explicit downgrade and
the rationale (including any observed bug/regression) so future reviewers
understand why v1.0.102 was chosen.

github.com/projectdiscovery/utils v0.4.20
github.com/rs/xid v1.5.0
github.com/stretchr/testify v1.11.1
golang.org/x/net v0.47.0
Comment on lines +12 to +24
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

❓ Verification inconclusive

Script executed:

#!/bin/bash
# Check git history for these dependency versions to determine if this is a revert

echo "=== Checking cdncheck version history ==="
git log --all --oneline -S 'github.com/projectdiscovery/cdncheck v1.1.36' -- go.mod | head -5

echo ""
echo "=== Checking utils version history ==="
git log --all --oneline -S 'github.com/projectdiscovery/utils v0.4.20' -- go.mod | head -5

echo ""
echo "=== Checking retryabledns version history ==="
git log --all --oneline -S 'github.com/projectdiscovery/retryabledns v1.0.102' -- go.mod | head -5

echo ""
echo "=== Checking recent go.mod changes on dev branch ==="
git log --oneline origin/dev -- go.mod | head -10

Repository: projectdiscovery/dnsx


Repository: projectdiscovery/dnsx
Script execution failed with error: Request timed out after 120000ms (requestId=bf2c281a-5658-4f18-8353-f4f4ae26df0e)


Script executed:

# First, let's read the go.mod file to confirm the versions
head -30 go.mod

Repository: projectdiscovery/dnsx


Repository: projectdiscovery/dnsx
Exit code: 0

stdout:

module github.com/projectdiscovery/dnsx

go 1.24.0

toolchain go1.24.5

require (
	github.com/logrusorgru/aurora v2.0.3+incompatible
	github.com/miekg/dns v1.1.62
	github.com/pkg/errors v0.9.1
	github.com/projectdiscovery/asnmap v1.1.1
	github.com/projectdiscovery/cdncheck v1.1.36
	github.com/projectdiscovery/clistats v0.1.1
	github.com/projectdiscovery/goconfig v0.0.1
	github.com/projectdiscovery/goflags v0.1.74
	github.com/projectdiscovery/gologger v1.1.56
	github.com/projectdiscovery/hmap v0.0.90
	github.com/projectdiscovery/mapcidr v1.1.34
	github.com/projectdiscovery/ratelimit v0.0.81
	github.com/projectdiscovery/retryabledns v1.0.102
	github.com/projectdiscovery/utils v0.4.20
	github.com/rs/xid v1.5.0
	github.com/stretchr/testify v1.11.1
	golang.org/x/net v0.47.0
)

require (
	aead.dev/minisign v0.2.0 // indirect
	github.com/Masterminds/semver/v3 v3.2.1 // indirect
	github.com/Mzack9999/gcache v0.0.0-20230410081825-519e28eab057 // indirect

Script executed:

# Check the full go.mod file to see all dependencies
wc -l go.mod

Repository: projectdiscovery/dnsx


Repository: projectdiscovery/dnsx
Exit code: 0

stdout:

134 go.mod

Script executed:

# Search for usage of the key downgraded libraries in the codebase
rg "github.com/projectdiscovery/utils" --type go -A 2 | head -30

Repository: projectdiscovery/dnsx


Repository: projectdiscovery/dnsx
Exit code: 0

stdout:

internal/runner/banner.go:	"github.com/projectdiscovery/utils/auth/pdcp"
internal/runner/banner.go:	updateutils "github.com/projectdiscovery/utils/update"
internal/runner/banner.go-)
internal/runner/banner.go-
--
internal/runner/util.go:	fileutil "github.com/projectdiscovery/utils/file"
internal/runner/util.go-	"golang.org/x/net/publicsuffix"
internal/runner/util.go-)
--
internal/runner/runner_test.go:	stringsutil "github.com/projectdiscovery/utils/strings"
internal/runner/runner_test.go-	"github.com/stretchr/testify/require"
internal/runner/runner_test.go-)
--
internal/runner/runner.go:	fileutil "github.com/projectdiscovery/utils/file"
internal/runner/runner.go:	iputil "github.com/projectdiscovery/utils/ip"
internal/runner/runner.go:	mapsutil "github.com/projectdiscovery/utils/maps"
internal/runner/runner.go:	sliceutil "github.com/projectdiscovery/utils/slice"
internal/runner/runner.go-)
internal/runner/runner.go-
--
internal/runner/options.go:	"github.com/projectdiscovery/utils/auth/pdcp"
internal/runner/options.go:	"github.com/projectdiscovery/utils/env"
internal/runner/options.go:	fileutil "github.com/projectdiscovery/utils/file"
internal/runner/options.go:	updateutils "github.com/projectdiscovery/utils/update"
internal/runner/options.go-)
internal/runner/options.go-
--
internal/runner/healthcheck.go:	fileutil "github.com/projectdiscovery/utils/file"
internal/runner/healthcheck.go-)
internal/runner/healthcheck.go-

Script executed:

# Check for usage of retryabledns
rg "retryabledns" --type go -B 2 -A 2 | head -30

Repository: projectdiscovery/dnsx


Repository: projectdiscovery/dnsx
Exit code: 0

stdout:

internal/runner/options.go-	options := &Options{}
internal/runner/options.go-	flagSet := goflags.NewFlagSet()
internal/runner/options.go:	flagSet.SetDescription(`dnsx is a fast and multi-purpose DNS toolkit allow to run multiple probes using retryabledns library.`)
internal/runner/options.go-
internal/runner/options.go-	flagSet.CreateGroup("input", "Input",
--
internal/runner/options.go-		}
internal/runner/options.go-		options.Response = true
internal/runner/options.go:		// the ANY query type is not supported by the retryabledns library,
internal/runner/options.go-		// thus it's hard to filter the results when it's used in combination with other query types
internal/runner/options.go-		options.ExcludeType = append(options.ExcludeType, "any")
--
internal/runner/runner.go-	"github.com/projectdiscovery/mapcidr/asn"
internal/runner/runner.go-	"github.com/projectdiscovery/ratelimit"
internal/runner/runner.go:	"github.com/projectdiscovery/retryabledns"
internal/runner/runner.go-	fileutil "github.com/projectdiscovery/utils/file"
internal/runner/runner.go-	iputil "github.com/projectdiscovery/utils/ip"
--
internal/runner/runner.go-
internal/runner/runner.go-func New(options *Options) (*Runner, error) {
internal/runner/runner.go:	retryabledns.CheckInternalIPs = true
internal/runner/runner.go-
internal/runner/runner.go-	dnsxOptions := dnsx.DefaultOptions
--
internal/runner/runner.go-		// prepare in memory structure similarly to shuffledns
internal/runner/runner.go-		r.hm.Scan(func(k, v []byte) error {
internal/runner/runner.go:			var dnsdata retryabledns.DNSData
internal/runner/runner.go-			if err := json.Unmarshal(v, &dnsdata); err != nil {
internal/runner/runner.go-				// the item has no record - ignore
--

Script executed:

# Look for any PR description or comments explaining the downgrades
find . -name "*.md" -type f -exec grep -l "downgrade\|version\|dependency" {} \; | head -10

Repository: projectdiscovery/dnsx


Repository: projectdiscovery/dnsx
Exit code: 0

stdout:

./.github/ISSUE_TEMPLATE/issue-report.md
./README.md

Script executed:

# Check the current branch and recent commits
git status
git log -5 --oneline

Repository: projectdiscovery/dnsx


Repository: projectdiscovery/dnsx
Exit code: 0

stdout:

HEAD detached at FETCH_HEAD
nothing to commit, working tree clean
9ba00e5 build: update Go dependencies to newer versions

Script executed:

# Check if there's a PR template or description
find . -name "*.md" -type f | xargs grep -l "auto wildcard\|publicsuffix" 2>/dev/null | head -5

Repository: projectdiscovery/dnsx


Repository: projectdiscovery/dnsx
Exit code: 0


Script executed:

# Check the actual PR or branch information
git log --all --oneline --graph | head -20

Repository: projectdiscovery/dnsx


Repository: projectdiscovery/dnsx
Exit code: 0

stdout:

* 9ba00e5 build: update Go dependencies to newer versions
* fe80b18 version update
*   b05668c Merge pull request `#916` from projectdiscovery/fix/omit-raw-flag
|\  
| * 00c85d3 fix: remove RawResp from JSON output completely
* | 62d3a7a chore(deps): bump the modules group with 8 updates
* | 31932fd chore(deps): bump the modules group with 8 updates (`#922`)
* | 3ba9878 chore(deps): bump the modules group across 1 directory with 8 updates
* | 8c02098 chore(deps): bump the modules group with 4 updates (`#915`)
|/  
* 6aaab05 chore(deps): bump the modules group with 6 updates
* d2f53f4 chore(deps): bump the modules group across 1 directory with 9 updates
*   037e267 Merge pull request `#903` from jjhwan-h/fix/wd
|\  
| *   44a9b20 Merge branch 'dev' into pr/903
| |\  
| |/  
|/|   
* |   31d97f2 Merge pull request `#907` from geeknik/dev
|\ \  

Script executed:

# Look for any comments in go.mod about version choices
cat go.mod | grep -A 2 -B 2 "utils\|retryabledns\|cdncheck"

Repository: projectdiscovery/dnsx


Repository: projectdiscovery/dnsx
Exit code: 0

stdout:

	github.com/pkg/errors v0.9.1
	github.com/projectdiscovery/asnmap v1.1.1
	github.com/projectdiscovery/cdncheck v1.1.36
	github.com/projectdiscovery/clistats v0.1.1
	github.com/projectdiscovery/goconfig v0.0.1
--
	github.com/projectdiscovery/mapcidr v1.1.34
	github.com/projectdiscovery/ratelimit v0.0.81
	github.com/projectdiscovery/retryabledns v1.0.102
	github.com/projectdiscovery/utils v0.4.20
	github.com/rs/xid v1.5.0
	github.com/stretchr/testify v1.11.1

Script executed:

# Check if there's a go.sum that might give us hints about why these versions were chosen
grep "github.com/projectdiscovery/utils" go.sum | head -10

Repository: projectdiscovery/dnsx


Repository: projectdiscovery/dnsx
Exit code: 0

stdout:

github.com/projectdiscovery/utils v0.4.20 h1:7Fmjb+4YZJSzn7bL21sjF3wAR53eSi7VdAfDkDBUUwY=
github.com/projectdiscovery/utils v0.4.20/go.mod h1:RnC23+hI8j4drZFHQpMX92hV9++9d/yBeNr1pzcbF7Y=

Script executed:

# Show the previous version of go.mod to see what was before
git show HEAD~1:go.mod | grep -E "utils|retryabledns|cdncheck" | head -10

Repository: projectdiscovery/dnsx


Repository: projectdiscovery/dnsx
Exit code: 0

stderr:

fatal: invalid object name 'HEAD~1'.

Script executed:

# Check git blame or history for when these were last downgraded
git log --all --oneline --follow -- go.mod | head -20

Repository: projectdiscovery/dnsx


Repository: projectdiscovery/dnsx
Exit code: 0

stdout:

9ba00e5 build: update Go dependencies to newer versions
62d3a7a chore(deps): bump the modules group with 8 updates
31932fd chore(deps): bump the modules group with 8 updates (`#922`)
3ba9878 chore(deps): bump the modules group across 1 directory with 8 updates
8c02098 chore(deps): bump the modules group with 4 updates (`#915`)
6aaab05 chore(deps): bump the modules group with 6 updates
d2f53f4 chore(deps): bump the modules group across 1 directory with 9 updates
da2aebb chore(deps): bump the modules group across 1 directory with 6 updates
92dbe0b bump
ed433b2 chore(deps): bump the modules group across 1 directory with 8 updates
16bbeb8 bump retryabledns
cfdced5 chore(deps): bump the modules group with 9 updates
a596d0e bump go
ea44ab2 chore(deps): bump the modules group across 1 directory with 10 updates
f3d64a4 chore(deps): bump github.com/projectdiscovery/gologger
54cae21 chore(deps): bump github.com/projectdiscovery/retryablehttp-go
48bb5be chore(deps): bump github.com/projectdiscovery/fastdialer
b3309b6 chore(deps): bump github.com/projectdiscovery/hmap from 0.0.75 to 0.0.77
06e3a34 chore(deps): bump github.com/projectdiscovery/retryabledns
870631b chore(deps): bump github.com/projectdiscovery/fastdialer

Script executed:

# Show detailed diff of the go.mod changes in this commit
git show HEAD -- go.mod | head -80

Repository: projectdiscovery/dnsx


Repository: projectdiscovery/dnsx
Exit code: 0

stdout:

commit 9ba00e52ebc1f20d5ed1bcb683bd93767a8ebcc8
Author: supreme2580 <victoromorogbe69@gmail.com>
Date:   Fri Mar 13 12:07:14 2026 +0100

    build: update Go dependencies to newer versions
    
    Update several golang.org/x/* modules to newer versions:
    - golang.org/x/net from v0.33.0 to v0.47.0
    - golang.org/x/crypto from v0.31.0 to v0.45.0
    - golang.org/x/sys from v0.28.0 to v0.38.0
    - golang.org/x/text from v0.21.0 to v0.31.0
    - golang.org/x/mod from v0.18.0 to v0.29.0
    - golang.org/x/tools from v0.22.0 to v0.38.0
    - golang.org/x/sync from v0.10.0 to v0.18.0
    - golang.org/x/term from v0.27.0 to v0.37.0
    - golang.org/x/oauth2 from v0.11.0 to v0.27.0
    
    Remove unused github.com/golang/protobuf, google.golang.org/appengine, and google.golang.org/protobuf dependencies to keep the dependency tree clean.

diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..a3b6d60
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,134 @@
+module github.com/projectdiscovery/dnsx
+
+go 1.24.0
+
+toolchain go1.24.5
+
+require (
+	github.com/logrusorgru/aurora v2.0.3+incompatible
+	github.com/miekg/dns v1.1.62
+	github.com/pkg/errors v0.9.1
+	github.com/projectdiscovery/asnmap v1.1.1
+	github.com/projectdiscovery/cdncheck v1.1.36
+	github.com/projectdiscovery/clistats v0.1.1
+	github.com/projectdiscovery/goconfig v0.0.1
+	github.com/projectdiscovery/goflags v0.1.74
+	github.com/projectdiscovery/gologger v1.1.56
+	github.com/projectdiscovery/hmap v0.0.90
+	github.com/projectdiscovery/mapcidr v1.1.34
+	github.com/projectdiscovery/ratelimit v0.0.81
+	github.com/projectdiscovery/retryabledns v1.0.102
+	github.com/projectdiscovery/utils v0.4.20
+	github.com/rs/xid v1.5.0
+	github.com/stretchr/testify v1.11.1
+	golang.org/x/net v0.47.0
+)
+
+require (
+	aead.dev/minisign v0.2.0 // indirect
+	github.com/Masterminds/semver/v3 v3.2.1 // indirect
+	github.com/Mzack9999/gcache v0.0.0-20230410081825-519e28eab057 // indirect
+	github.com/Mzack9999/go-http-digest-auth-client v0.6.1-0.20220414142836-eb8883508809 // indirect
+	github.com/STARRY-S/zip v0.2.1 // indirect
+	github.com/VividCortex/ewma v1.2.0 // indirect
+	github.com/akrylysov/pogreb v0.10.1 // indirect
+	github.com/alecthomas/chroma/v2 v2.14.0 // indirect
+	github.com/andybalholm/brotli v1.1.1 // indirect
+	github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
+	github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
+	github.com/aymerick/douceur v0.2.0 // indirect
+	github.com/bodgit/plumbing v1.3.0 // indirect
+	github.com/bodgit/sevenzip v1.6.0 // indirect
+	github.com/bodgit/windows v1.0.1 // indirect
+	github.com/charmbracelet/glamour v0.8.0 // indirect
+	github.com/charmbracelet/lipgloss v0.13.0 // indirect
+	github.com/charmbracelet/x/ansi v0.3.2 // indirect
+	github.com/cheggaaa/pb/v3 v3.1.4 // indirect
+	github.com/cloudflare/circl v1.6.1 // indirect
+	github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 // indirect
+	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
+	github.com/dimchansky/utfbom v1.1.1 // indirect
+	github.com/dlclark/regexp2 v1.11.5 // indirect
+	github.com/docker/go-units v0.5.0 // indirect
+	github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect
+	github.com/fatih/color v1.15.0 // indirect
+	github.com/gaissmai/bart v0.26.0 // indirect

Undocumented dependency downgrades: Verify these versions are intentional and compatible.

This commit updates golang.org/x modules to newer versions but simultaneously downgrades 7 projectdiscovery/* packages without documentation:

  • cdncheck: v1.2.13 → v1.1.36
  • gologger: v1.1.62 → v1.1.56
  • hmap: v0.0.98 → v0.0.90
  • mapcidr: v1.1.97 → v1.1.34
  • ratelimit: v0.0.82 → v0.0.81
  • retryabledns: v1.0.111 → v1.0.102
  • utils: v0.7.3 → v0.4.20

The commit message only mentions golang.org/x updates and does not explain these downgrades. They appear to be unintentional side effects from Go's dependency resolver. Confirm that these downgraded versions are:

  1. Intentional, with documented rationale
  2. API-compatible with code that imports utils subpackages (fileutil, iputil, mapsutil, sliceutil), calls retryabledns.CheckInternalIPs, and unmarshals retryabledns.DNSData
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@go.mod` around lines 12 - 24, The go.mod changes show unintended downgrades
of several projectdiscovery/* modules; verify whether these version changes are
intentional and either pin the intended versions or document the rationale:
inspect and update go.mod to the correct versions for
github.com/projectdiscovery/{cdncheck,gologger,hmap,mapcidr,ratelimit,retryabledns,utils}
(or add a clear commit message/CHANGELOG entry explaining the downgrade), run
`go get`/`go mod tidy` to lock them, then run full tests and static checks to
confirm API compatibility with code that imports utils subpackages (fileutil,
iputil, mapsutil, sliceutil) and with retryabledns.CheckInternalIPs and the
retryabledns.DNSData unmarshalling; if incompatibilities are found, either
restore newer versions or adapt call sites accordingly and document the
decision.

)

require (
Expand Down Expand Up @@ -82,12 +83,12 @@ require (
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/projectdiscovery/blackrock v0.0.1 // indirect
github.com/projectdiscovery/fastdialer v0.4.19 // indirect
github.com/projectdiscovery/fastdialer v0.4.1 // indirect
github.com/projectdiscovery/freeport v0.0.7 // indirect
github.com/projectdiscovery/machineid v0.0.0-20240226150047-2e2c51e35983 // indirect
github.com/projectdiscovery/networkpolicy v0.1.31 // indirect
github.com/projectdiscovery/retryablehttp-go v1.1.0 // indirect
github.com/refraction-networking/utls v1.7.1 // indirect
github.com/projectdiscovery/networkpolicy v0.1.1 // indirect
github.com/projectdiscovery/retryablehttp-go v1.0.111 // indirect
github.com/refraction-networking/utls v1.6.7 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
Expand All @@ -98,16 +99,16 @@ require (
github.com/therootcompany/xz v1.0.1 // indirect
github.com/tidwall/btree v1.6.0 // indirect
github.com/tidwall/buntdb v1.3.0 // indirect
github.com/tidwall/gjson v1.18.0 // indirect
github.com/tidwall/gjson v1.14.4 // indirect
github.com/tidwall/grect v0.1.4 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tidwall/rtred v0.1.2 // indirect
github.com/tidwall/tinyqueue v0.1.1 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/ulikunitz/xz v0.5.15 // indirect
github.com/weppos/publicsuffix-go v0.40.3-0.20250408071509-6074bbe7fd39 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
github.com/weppos/publicsuffix-go v0.30.1 // indirect
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Inconsistent: Downgrading publicsuffix-go while adding publicsuffix-based feature.

This PR enhances extractDomain to use eTLD+1 resolution via golang.org/x/net/publicsuffix (line 24), yet downgrades the indirect publicsuffix-go dependency from v0.40.x to v0.30.1. While publicsuffix-go is indirect, downgrading a domain-suffix library during a feature that relies on public suffix logic is inconsistent and warrants explanation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@go.mod` at line 111, The go.mod downgrade of
github.com/weppos/publicsuffix-go to v0.30.1 is inconsistent with the new
extractDomain change that relies on publicsuffix logic; update the go.mod to a
current compatible version (e.g. v0.40.x) or remove the explicit older indirect
requirement so the module graph resolves the newer publicsuffix implementation,
then run go mod tidy to refresh sums; ensure extractDomain references the
golang.org/x/net/publicsuffix behavior you expect after the dependency change.

github.com/yuin/goldmark v1.7.4 // indirect
github.com/yuin/goldmark-emoji v1.0.3 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
Expand All @@ -118,9 +119,8 @@ require (
go.uber.org/multierr v1.11.0 // indirect
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
golang.org/x/crypto v0.45.0 // indirect
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
golang.org/x/exp v0.0.0-20230420155640-133eef4313cb // indirect
golang.org/x/mod v0.29.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/oauth2 v0.27.0 // indirect
golang.org/x/sync v0.18.0 // indirect
golang.org/x/sys v0.38.0 // indirect
Expand Down
73 changes: 43 additions & 30 deletions go.sum

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions internal/runner/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ type Options struct {
TraceMaxRecursion int
WildcardThreshold int
WildcardDomain string
AutoWildcard bool
ShowStatistics bool
rcodes map[int]struct{}
RCode string
Expand Down Expand Up @@ -189,6 +190,7 @@ func ParseOptions() *Options {
flagSet.StringVarP(&options.Resolvers, "resolver", "r", "", "list of resolvers to use (file or comma separated)"),
flagSet.IntVarP(&options.WildcardThreshold, "wildcard-threshold", "wt", 5, "wildcard filter threshold"),
flagSet.StringVarP(&options.WildcardDomain, "wildcard-domain", "wd", "", "domain name for wildcard filtering (other flags will be ignored - only json output is supported)"),
flagSet.BoolVarP(&options.AutoWildcard, "auto-wildcard", "aw", false, "enable automatic wildcard filtering"),
flagSet.StringVar(&options.Proxy, "proxy", "", "proxy to use (eg socks5://127.0.0.1:8080)"),
)

Expand Down
12 changes: 8 additions & 4 deletions internal/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func New(options *Options) (*Runner, error) {
}

// If no option is specified or wildcard filter has been requested use query type A
if len(questionTypes) == 0 || options.WildcardDomain != "" {
if len(questionTypes) == 0 || options.WildcardDomain != "" || options.AutoWildcard {
options.A = true
questionTypes = append(questionTypes, dns.TypeA)
}
Expand Down Expand Up @@ -467,7 +467,7 @@ func (r *Runner) run() error {
close(r.outputchan)
r.wgoutputworker.Wait()

if r.options.WildcardDomain != "" {
if r.options.WildcardDomain != "" || r.options.AutoWildcard {
gologger.Print().Msgf("Starting to filter wildcard subdomains\n")
ipDomain := make(map[string]map[string]struct{})
listIPs := []string{}
Expand Down Expand Up @@ -524,7 +524,11 @@ func (r *Runner) run() error {
numRemovedSubdomains := 0
for _, A := range listIPs {
for host := range ipDomain[A] {
if host == r.options.WildcardDomain {
wildcardDomain := r.options.WildcardDomain
if r.options.AutoWildcard {
wildcardDomain = extractDomain(host)
}
if host == wildcardDomain {
if _, ok := seen[host]; !ok {
seen[host] = struct{}{}
_ = r.lookupAndOutput(host)
Expand Down Expand Up @@ -731,7 +735,7 @@ func (r *Runner) worker() {
}
}
// if wildcard filtering just store the data
if r.options.WildcardDomain != "" {
if r.options.WildcardDomain != "" || r.options.AutoWildcard {
if err := r.storeDNSData(dnsData.DNSData); err != nil {
gologger.Debug().Msgf("Failed to store DNS data for %s: %v\n", domain, err)
}
Expand Down
25 changes: 21 additions & 4 deletions internal/runner/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"time"

fileutil "github.com/projectdiscovery/utils/file"
"golang.org/x/net/publicsuffix"
)

const (
Expand Down Expand Up @@ -43,12 +44,28 @@ func isURL(toTest string) bool {
}

func extractDomain(URL string) string {
u, err := url.Parse(URL)
if err != nil {
return ""
var host string
if !strings.Contains(URL, "://") && !isURL(URL) {
host = strings.TrimSuffix(URL, ".")
} else {
u, err := url.Parse(URL)
if err != nil {
return ""
}
host = strings.TrimSuffix(u.Hostname(), ".")
}

return u.Hostname()
// Use public suffix list for accurate eTLD+1 extraction
domain, err := publicsuffix.EffectiveTLDPlusOne(host)
if err != nil {
// fallback to last two parts if publicsuffix fails
parts := strings.Split(host, ".")
if len(parts) >= 2 {
return strings.Join(parts[len(parts)-2:], ".")
}
return host
}
return domain
}

func prepareResolver(resolver string) string {
Expand Down
26 changes: 26 additions & 0 deletions internal/runner/util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package runner

import (
"testing"
"github.com/stretchr/testify/require"
)

func TestExtractDomain(t *testing.T) {
tests := []struct {
input string
expected string
}{
{"example.com", "example.com"},
{"sub.example.com", "example.com"},
{"foo.bar.co.uk", "bar.co.uk"},
{"api.service.com.au", "service.com.au"},
{"foo.example.com.", "example.com"},
{"https://sub.example.com/path", "example.com"},
{"http://foo.bar.co.uk:8080", "bar.co.uk"},
}

for _, tc := range tests {
got := extractDomain(tc.input)
require.Equal(t, tc.expected, got, "input: %s", tc.input)
}
}
19 changes: 15 additions & 4 deletions internal/runner/wildcard.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,30 @@ func (r *Runner) IsWildcard(host string) bool {
orig[A] = struct{}{}
}

subdomainPart := strings.TrimSuffix(host, "."+r.options.WildcardDomain)
var wildcardDomain string
if r.options.AutoWildcard {
wildcardDomain = extractDomain(host)
} else {
wildcardDomain = r.options.WildcardDomain
}

if wildcardDomain == "" {
return false
}

subdomainPart := strings.TrimSuffix(host, "."+wildcardDomain)
subdomainTokens := strings.Split(subdomainPart, ".")

// Build an array by preallocating a slice of a length
// and create the wildcard generation prefix.
// We use a rand prefix at the beginning like %rand%.domain.tld
// A permutation is generated for each level of the subdomain.
var hosts []string
hosts = append(hosts, r.options.WildcardDomain)
hosts := make([]string, 0, len(subdomainTokens)+1)
hosts = append(hosts, wildcardDomain)

if len(subdomainTokens) > 0 {
for i := 1; i < len(subdomainTokens); i++ {
newhost := strings.Join(subdomainTokens[i:], ".") + "." + r.options.WildcardDomain
newhost := strings.Join(subdomainTokens[i:], ".") + "." + wildcardDomain
hosts = append(hosts, newhost)
}
}
Expand Down