Skip to content

fix: preserve explicit target port in network templates (fixes #7323) - #7465

Merged
Mzack9999 merged 3 commits into
projectdiscovery:devfrom
XananasX7:fix/network-port-override
Jun 16, 2026
Merged

fix: preserve explicit target port in network templates (fixes #7323)#7465
Mzack9999 merged 3 commits into
projectdiscovery:devfrom
XananasX7:fix/network-port-override

Conversation

@XananasX7

@XananasX7 XananasX7 commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Problem

When a user explicitly specifies a port on the CLI:

nuclei -target TARGET:80 -t network/cves/2001/CVE-2001-1473.yaml

Nuclei ignores the user's port and connects to the template's port (e.g. 22) instead:

[WRN] [CVE-2001-1473] Could not make network request for (TARGET:22): could not connect...

This makes it impossible to scan services running on non-standard ports — SSH on 80, FTP on 443, etc. The target is silently scanned on the wrong port.

Root Cause

UseNetworkPort() in contextargs.go unconditionally replaces any port in reservedPorts (80, 443, 8080, …) with the template port, even when the operator deliberately typed TARGET:80.

The function cannot distinguish between:

  • http://TARGET:80 — port 80 is scheme-implied, replacing it is correct
  • TARGET:80 — port 80 is explicitly chosen, replacing it is wrong

Fix

Only replace a reserved port when the input contains a URL scheme (://), which means the port was implied by the scheme rather than typed by the operator.

A bare host:port form means the operator chose that port on purpose — it is preserved unchanged.

Change in contextargs.go is ~15 lines.

Tests

Seven table-driven cases added to contextargs_test.go (new file):

Case Input Template port Expected
No port in input example.com 22 example.com:22
Explicit non-reserved port example.com:2222 22 example.com:2222
Bare host:80 (regression #7323) example.com:80 22 example.com:80
Scheme-implied port 80 http://example.com:80 22 example.com:22
HTTP scheme no port http://example.com 8888 example.com:8888
Empty template port example.com:9999 (empty) example.com:9999
Explicit port == template port example.com:22 22 example.com:22

All pass.

Related

Fixes #7323


Would it be possible to add a 💎 Bounty label to this issue/PR? The bug completely silences scanning of services on non-standard ports, which is a meaningful impact for anyone doing custom port scanning with nuclei.

Summary by CodeRabbit

  • Bug Fixes
    • Improved network port handling to respect explicitly provided host:port inputs.
    • Reserved HTTP/DNS ports are replaced only when the input includes a URL scheme (http:///https://); scheme-less host:port values are preserved.
    • Added a regression test to ensure operator-specified ports aren’t overridden by templates.
  • Tests
    • Expanded coverage for IPv6 handling, service-name-to-port exclusions, and idempotent behavior on repeated runs.

…tdiscovery#7323)

Problem
-------
When a user specifies a port explicitly on the command line, e.g.:

  nuclei -target TARGET:80 -t network/cves/2001/CVE-2001-1473.yaml

UseNetworkPort() was overriding port 80 with the template's port (22).
This happened because reservedPorts (80, 443, 8080, …) were always
replaced by the template port, regardless of whether the port was
deliberately chosen by the operator or merely implied by the URL scheme.

As a result, services running on non-standard ports (SSH on 80, FTP on
443, etc.) were silently scanned on the wrong port, or the connection
was refused, and the target was effectively invisible to Nuclei.

Root cause
----------
UseNetworkPort() treated a bare 'host:80' the same as 'http://host:80'.
In the former the operator explicitly chose port 80; in the latter the
port was implied by the http:// scheme.

Fix
---
Only replace a reserved port when the input contains a URL scheme
('://'), indicating the port was scheme-implied.

A bare 'host:port' form means the operator deliberately chose that port
and it is preserved unchanged.

Regression tests
----------------
Seven table-driven cases added to contextargs_test.go covering:
- No port in input  → template port used (existing behaviour)
- Explicit non-reserved port → preserved
- Bare host:80 (key regression) → preserved
- http://host:80 (scheme-implied) → replaced
- http://host (no port) → template port used
- Empty template port → no-op
- Explicit port == template port → unchanged

Fixes projectdiscovery#7323
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: abb241ff-0407-4714-ba4c-8697aa403de6

📥 Commits

Reviewing files that changed from the base of the PR and between f44a9b9 and 8e6a070.

📒 Files selected for processing (1)
  • internal/tests/integration/network_test.go

Walkthrough

Context.UseNetworkPort is updated to distinguish scheme-implied reserved ports (http://host:80) from explicitly operator-specified bare ports (host:80). An early-return branch handles portless inputs. A comprehensive test suite covers all port-override, port-preservation, IPv6, service-name, and idempotence scenarios, validated by a regression integration test.

Changes

UseNetworkPort port-override fix

Layer / File(s) Summary
UseNetworkPort logic and comment update
pkg/protocols/common/contextargs/contextargs.go
Expands the method comment to document scheme-implied vs. explicit-port distinction. Adds an early return when the input has no port (sets and returns immediately). Gates reserved-port replacement on the input containing a URL scheme (://), leaving bare host:port inputs untouched.
Comprehensive unit test suite
pkg/protocols/common/contextargs/contextargs_test.go
TestUseNetworkPort covers no-port, explicit non-reserved ports, bare :80 (preserved), http://...:80 (overridden), template port application, and excludePorts behavior with multi-value support. TestUseNetworkPortIPv6 verifies bracketed IPv6 address handling. TestUseNetworkPortServiceNameExclude confirms service-name resolution in excludePorts. TestUseNetworkPortIdempotent validates stability across repeated calls.
Integration test for NetworkPort regression
internal/tests/integration/network_test.go
Replaces URL-rewrite-based test with a dedicated regression check: starts a TCP server on an explicitly specified port (8081), runs network-port.yaml template, and verifies the template uses the operator-specified port instead of overriding. Removes unused strings import.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐇 Hop along, little packet, find your port!
No scheme? Your :80 shall not be swapped short.
But http:// implies it — override away!
The rabbit checked the scheme before the fray.
Now SSH on port 80 gets its day! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: preserving explicit target ports in network templates, and directly references the issue #7323 being resolved.
Linked Issues check ✅ Passed The PR fully addresses issue #7323 by fixing the bug where explicitly specified ports were being overridden, implementing the distinction between bare host:port and scheme-implied ports.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the port preservation bug: the logic fix in contextargs.go, comprehensive test coverage in contextargs_test.go, and a regression test in network_test.go.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Mzack9999
Mzack9999 merged commit 0d78558 into projectdiscovery:dev Jun 16, 2026
19 checks passed
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.

[BUG] networking services on HTTP ports are never scanned

2 participants