Skip to content

Accuracy fixed - #163

Open
rix4uni wants to merge 1 commit into
projectdiscovery:mainfrom
rix4uni:main
Open

Accuracy fixed#163
rix4uni wants to merge 1 commit into
projectdiscovery:mainfrom
rix4uni:main

Conversation

@rix4uni

@rix4uni rix4uni commented Apr 19, 2026

Copy link
Copy Markdown

check this issue: #162

@neo-by-projectdiscovery-dev

neo-by-projectdiscovery-dev Bot commented Apr 19, 2026

Copy link
Copy Markdown

Neo - PR Security Review

Caution

Neo couldn't finish analyzing this pull request during this run. Please run the review again.

Comment @pdneo help for available commands. · Open in Neo

@dogancanbakir dogancanbakir linked an issue Apr 20, 2026 that may be closed by this pull request

@Mzack9999 Mzack9999 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the PR, the direction is good and the EnrichWithInfo / EnrichWithCats split is a nice cleanup. Two main asks before this can land.

Switch the headless backend from chromedp to go-rod. Built in browser pooling, WaitStable for SPA hydration, and HijackRequests for full response capture solve most of the rough edges of the current implementation, and go-rod is already used elsewhere in our stack. With one shared rod.Browser on the client and a fresh page per call we also avoid spawning a Chromium process on every invocation.

Rename FingerprintURL to FingerprintHeadless (and the WithInfo / WithCats variants accordingly). The current name reads like a static URL fetch and breaks the WithX naming pattern used everywhere else in the package, where WithX means the return value carries extra X.

Also please revert the go.mod toolchain bump from 1.25.0 to 1.26.2, looks accidental from a local toolchain. Once the backend is go-rod, hide the headless file behind a build tag or move it to a headless/ sub package so static only consumers don't inherit the browser dep tree.

A few smaller things left inline.

Comment thread fingerprint_headless.go
}

// FingerprintURL checks the provided URL using headless browser (chromedp) for deep JS & DOM fingerprinting
func (s *Wappalyze) FingerprintURL(ctx context.Context, url string) (map[string]struct{}, error) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please rename to FingerprintHeadless (with FingerprintHeadlessWithInfo and FingerprintHeadlessWithCats following). FingerprintURL reads like a static fetch helper and the WithX suffix in this package is reserved for return shape, not mechanism.

While renaming, also worth moving this surface onto a small Headless sub client returned by Wappalyze.Headless(). It gives a natural home for the shared browser, options, and a Close method, none of which fit on Wappalyze itself.

Comment thread fingerprint_headless.go
jsGlobals = make(map[string]string)
domMatches = make(map[string]map[string]string)

c, cancel := chromedp.NewContext(ctx)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Switch this whole flow to go-rod. One rod.Browser held on the client, one rod.Page per call, page.WaitStable instead of a fixed sleep, and page.HijackRequests to capture all response headers and cookies cleanly. Most of the current race and lifecycle concerns disappear with that rewrite.

Comment thread fingerprints.go
var domMatched bool
for attr, pattern := range attrPatterns {
var attrValue string
if attr == "main" {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

text and exists are collapsed to the same compiled key main upstream, which loses the info this branch needs to know whether to look at el.textContent or just existence. End result is every text rule on the headless path matches against the literal string true. Keep the kind on the compiled struct, either as separate maps or a small enum, so the headless side can dispatch correctly.

Comment thread README.md
headlessFingerprintsWithCats := wappalyzerClient.EnrichWithCats(headlessFingerprints)
fmt.Printf("Categories: %v\n", headlessFingerprintsWithCats)

// Output: map[Acquia Cloud Platform:{} Amazon EC2:{} Apache:{} Cloudflare:{} Drupal:{} PHP:{} Percona:{} React:{} Varnish:{}]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This Output comment is copy pasted from the static cetus.zone example and has nothing to do with hackerone.com or with what the headless API would return. Please drop it or replace with a real sample.

Comment thread examples/static/main.go
@@ -0,0 +1,29 @@
package main

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This duplicates examples/main.go. Please either remove examples/main.go in favor of the new structure or drop this file. Three near identical static examples is confusing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Not detecting accurate technologies

2 participants