shadow1ng/fscan · error

%s: %w (webscan_request_create_error)

Error message

%s: %w (webscan_request_create_error)

What it means

Returned by the rule-execution path in webscan/lib/poc_executor.go when http.NewRequestWithContext fails while building the per-rule probe request from the POC rule's method, path, and body. The error is wrapped with the localized 'request create error' message. This means the constructed request URL (scheme://host+path) or the rule's method is invalid at the net/http level.

Source

Thrown at webscan/lib/poc_executor.go:227

		}

		// 构建请求路径
		if oReq.URL.Path != "" && oReq.URL.Path != "/" {
			req.URL.Path = fmt.Sprint(oReq.URL.Path, rule.Path)
		} else {
			req.URL.Path = rule.Path
		}
		req.URL.Path = strings.ReplaceAll(req.URL.Path, " ", "%20")

		// 创建新请求(传递原始请求的Context以支持超时控制)
		newRequest, err := http.NewRequestWithContext(
			oReq.Context(),
			rule.Method,
			fmt.Sprintf("%s://%s%s", req.URL.Scheme, req.URL.Host, req.URL.Path),
			strings.NewReader(rule.Body),
		)
		if err != nil {
			return false, fmt.Errorf("%s: %w", i18n.GetText("webscan_request_create_error"), err)
		}

		// 设置请求头
		newRequest.Header = oReq.Header.Clone()
		for k, v := range Headers {
			newRequest.Header.Set(k, v)
		}
		_ = Headers // 清空Headers

		// 发送请求
		resp, err := DoRequest(newRequest, rule.FollowRedirects, session)
		newRequest = nil
		if err != nil {
			if isTransportError(err) {
				return false, nil
			}
			return false, err
		}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Read the inner error: it names the offending part ("invalid method", "parse \"...\": invalid URI", "empty url").
  2. Check the POC rule's method and path fields for typos, spaces, or stray characters.
  3. Ensure the target request has a valid Scheme and Host so the composed scheme://host+path URL is well-formed.
  4. URL-escape the rule path (spaces to %20) and validate variable substitution left no raw {{var}} braces in the final URL.

Example fix

// before
rule := Rules{Method: "GET /", Path: "/api/{{token}}"} // creates invalid request
// after
rule := Rules{Method: "GET", Path: "/api/" + url.PathEscape(token)}
Defensive patterns

Strategy: validation

Validate before calling

func validRule(rule Rules, base *Request) error {
    if strings.ContainsAny(rule.Method, " \t") {
        return fmt.Errorf("invalid method %q", rule.Method)
    }
    u := fmt.Sprintf("%s://%s%s", base.URL.Scheme, base.URL.Host, rule.Path)
    if _, err := url.Parse(u); err != nil {
        return fmt.Errorf("rule produces invalid URL %q: %w", u, err)
    }
    return nil
}

Type guard

func ruleURLOK(scheme, host, path string) bool {
    if host == "" || scheme == "" {
        return false
    }
    _, err := url.Parse(scheme + "://" + host + path)
    return err == nil
}

Try / catch

ok, err := executeRules(req, poc, vars, parsed, env, session, cache)
if err != nil {
    if strings.Contains(err.Error(), i18n.GetText("webscan_request_create_error")) {
        log.Printf("bad POC rule in %s: %v", poc.Name, err)
        return
    }
    return err
}

Prevention

When it happens

Trigger: A POC rule whose Path, after variable substitution, produces an invalid URL string (e.g. contains characters net/http rejects, empty host in req.URL, or an unparsable combined URL), or rule.Method contains invalid characters/spaces, so http.NewRequestWithContext returns an error.

Common situations: A hand-written POC with a typo in `path:` or `method:` (e.g. "GET /" with a space in method, or a path with raw braces/quotes left after failed variable substitution); a rule path that yields `http://host` with an empty host when the parsed request lost its Host field; crafted targets whose path merges badly with the rule path.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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