{"record":{"id":"83a620c8c740c077","repo":"shadow1ng/fscan","slug":"s-w-webscan-request-create-error","errorCode":null,"errorMessage":"%s: %w (webscan_request_create_error)","messagePattern":"(.+?): %w \\(webscan_request_create_error\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"webscan/lib/poc_executor.go","lineNumber":227,"sourceCode":"\t\t}\n\n\t\t// 构建请求路径\n\t\tif oReq.URL.Path != \"\" && oReq.URL.Path != \"/\" {\n\t\t\treq.URL.Path = fmt.Sprint(oReq.URL.Path, rule.Path)\n\t\t} else {\n\t\t\treq.URL.Path = rule.Path\n\t\t}\n\t\treq.URL.Path = strings.ReplaceAll(req.URL.Path, \" \", \"%20\")\n\n\t\t// 创建新请求（传递原始请求的Context以支持超时控制）\n\t\tnewRequest, err := http.NewRequestWithContext(\n\t\t\toReq.Context(),\n\t\t\trule.Method,\n\t\t\tfmt.Sprintf(\"%s://%s%s\", req.URL.Scheme, req.URL.Host, req.URL.Path),\n\t\t\tstrings.NewReader(rule.Body),\n\t\t)\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"%s: %w\", i18n.GetText(\"webscan_request_create_error\"), err)\n\t\t}\n\n\t\t// 设置请求头\n\t\tnewRequest.Header = oReq.Header.Clone()\n\t\tfor k, v := range Headers {\n\t\t\tnewRequest.Header.Set(k, v)\n\t\t}\n\t\t_ = Headers // 清空Headers\n\n\t\t// 发送请求\n\t\tresp, err := DoRequest(newRequest, rule.FollowRedirects, session)\n\t\tnewRequest = nil\n\t\tif err != nil {\n\t\t\tif isTransportError(err) {\n\t\t\t\treturn false, nil\n\t\t\t}\n\t\t\treturn false, err\n\t\t}","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/webscan/lib/poc_executor.go#L209-L245","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the inner error: it names the offending part (\"invalid method\", \"parse \\\"...\\\": invalid URI\", \"empty url\").","Check the POC rule's method and path fields for typos, spaces, or stray characters.","Ensure the target request has a valid Scheme and Host so the composed scheme://host+path URL is well-formed.","URL-escape the rule path (spaces to %20) and validate variable substitution left no raw {{var}} braces in the final URL."],"exampleFix":"// before\nrule := Rules{Method: \"GET /\", Path: \"/api/{{token}}\"} // creates invalid request\n// after\nrule := Rules{Method: \"GET\", Path: \"/api/\" + url.PathEscape(token)}","handlingStrategy":"validation","validationCode":"func validRule(rule Rules, base *Request) error {\n    if strings.ContainsAny(rule.Method, \" \\t\") {\n        return fmt.Errorf(\"invalid method %q\", rule.Method)\n    }\n    u := fmt.Sprintf(\"%s://%s%s\", base.URL.Scheme, base.URL.Host, rule.Path)\n    if _, err := url.Parse(u); err != nil {\n        return fmt.Errorf(\"rule produces invalid URL %q: %w\", u, err)\n    }\n    return nil\n}","typeGuard":"func ruleURLOK(scheme, host, path string) bool {\n    if host == \"\" || scheme == \"\" {\n        return false\n    }\n    _, err := url.Parse(scheme + \"://\" + host + path)\n    return err == nil\n}","tryCatchPattern":"ok, err := executeRules(req, poc, vars, parsed, env, session, cache)\nif err != nil {\n    if strings.Contains(err.Error(), i18n.GetText(\"webscan_request_create_error\")) {\n        log.Printf(\"bad POC rule in %s: %v\", poc.Name, err)\n        return\n    }\n    return err\n}","preventionTips":["Keep POC rule `method` values to a single valid HTTP token","URL-escape rule paths and substituted variable values","Verify the base request retains Scheme and Host before rule execution","Test new POCs against a benign local target before production scans"],"tags":["go","webscan","http","request-construction"],"backgroundTag":"invalid-url-format","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}