shadow1ng/fscan · error · ErrInvalidURL

%w: invalid port %q (ErrInvalidURL)

Error message

%w: invalid port %q (ErrInvalidURL)

What it means

When the URL has an explicit port string, buildTargetURL parses it with strconv.Atoi and requires 1-65535; otherwise it wraps ErrInvalidURL with the offending port quoted. This is a strict numeric/range validation of the port extracted by url.Parse.

Source

Thrown at webscan/web_scan.go:125

	}

	// 解析URL以提取基础部分
	parsedURL, err := url.Parse(info.URL)
	if err != nil {
		return "", fmt.Errorf("%w: %w", ErrInvalidURL, err)
	}
	if parsedURL.Hostname() == "" {
		return "", fmt.Errorf("%w: empty host", ErrInvalidURL)
	}
	portStr := parsedURL.Port()
	if portStr == "" {
		if hasMalformedWebURLPort(parsedURL.Host) {
			return "", fmt.Errorf("%w: invalid port", ErrInvalidURL)
		}
	} else {
		port, err := strconv.Atoi(portStr)
		if err != nil || port < 1 || port > 65535 {
			return "", fmt.Errorf("%w: invalid port %q", ErrInvalidURL, portStr)
		}
	}
	parsedURL.Host = normalizeWebURLHost(parsedURL.Host)

	return fmt.Sprintf("%s://%s", parsedURL.Scheme, parsedURL.Host), nil
}

// hasProtocolPrefix 检查URL是否包含协议前缀
func hasProtocolPrefix(urlStr string) bool {
	urlStr = strings.ToLower(urlStr)
	return strings.HasPrefix(urlStr, protocolHTTP) || strings.HasPrefix(urlStr, protocolHTTPS)
}

func isTLSPort(port int) bool {
	switch port {
	case 443, 8443, 4443, 9443:
		return true
	default:

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Use a valid port in 1-65535 (e.g. :8080, :443)
  2. Ensure template variables supplying the port are substituted with numeric values
  3. Validate the port with strconv.Atoi + range check in the config layer before invoking WebScan

Example fix

// before
const url = "http://example.com:99999"
// after
const url = "http://example.com:8443"
Defensive patterns

Strategy: validation

Validate before calling

if p := u.Port(); p != "" {
    n, err := strconv.Atoi(p)
    if err != nil || n < 1 || n > 65535 {
        return fmt.Errorf("target %q has invalid port %q", target, p)
    }
}

Type guard

func validPort(s string) bool {
    n, err := strconv.Atoi(s)
    return err == nil && n >= 1 && n <= 65535
}

Try / catch

if err := WebScan(target); errors.Is(err, ErrInvalidURL) {
    log.Printf("rejecting target %q: %v", target, err)
    return nil
}

Prevention

When it happens

Trigger: URLs like http://example.com:0, http://example.com:99999, http://example.com:80a, or any non-numeric port segment after the colon (e.g. http://example.com:%PORT).

Common situations: Unsubstituted environment/templated variables (:${PORT}), typos in hardcoded ports, or port numbers copied from other protocols exceeding 65535.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/5538e3fbfdde61ac. Report an issue: GitHub.