{"record":{"id":"9c669fb7f6742fe4","repo":"shadow1ng/fscan","slug":"parser-ipv4-only-9c669f","errorCode":null,"errorMessage":"parser_ipv4_only","messagePattern":"parser_ipv4_only","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/parsers/parsers.go","lineNumber":400,"sourceCode":"\tstartNum, err := strconv.Atoi(ipParts[3])\n\tif err != nil || startNum > endNum {\n\t\treturn nil, fmt.Errorf(\"%s\", i18n.Tr(\"parser_invalid_ip_range_val\", startIPStr, endSuffix))\n\t}\n\n\tvar allIP []string\n\tfor i := startNum; i <= endNum; i++ {\n\t\tallIP = append(allIP, fmt.Sprintf(\"%s.%d\", prefixIP, i))\n\t}\n\n\treturn allIP, nil\n}\n\n// parseIPFullRange 解析完整格式的IP范围\nfunc parseIPFullRange(startIP, endIP net.IP) ([]string, error) {\n\tstart4 := startIP.To4()\n\tend4 := endIP.To4()\n\tif start4 == nil || end4 == nil {\n\t\treturn nil, fmt.Errorf(\"%s\", i18n.GetText(\"parser_ipv4_only\"))\n\t}\n\n\tstartInt := (int(start4[0]) << 24) | (int(start4[1]) << 16) | (int(start4[2]) << 8) | int(start4[3])\n\tendInt := (int(end4[0]) << 24) | (int(end4[1]) << 16) | (int(end4[2]) << 8) | int(end4[3])\n\n\tif startInt > endInt {\n\t\treturn nil, fmt.Errorf(\"%s\", i18n.GetText(\"parser_start_gt_end\"))\n\t}\n\n\tvar ips []string\n\tcurrent := make(net.IP, len(start4))\n\tcopy(current, start4)\n\n\tfor {\n\t\tips = append(ips, current.String())\n\t\tif current.Equal(end4) {\n\t\t\tbreak\n\t\t}","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/common/parsers/parsers.go#L382-L418","documentation":"parseIPFullRange converts both endpoints with To4() and requires them to be IPv4. If either endpoint is nil as IPv4 (e.g. an IPv6 address), this error is returned. The range engine only supports IPv4 expansion.","triggerScenarios":"Calling parseIPRangeString with a full range where start or end is IPv6, e.g. '2001:db8::1-2001:db8::5', or an unparseable endpoint that yields a nil To4().","commonSituations":"Scanning dual-stack hosts where users paste IPv6 addresses into an IPv4-only range field; mixed ranges like '192.168.1.1-2001:db8::2'.","solutions":["Use IPv4 addresses on both sides of the range, e.g. '192.168.1.1-192.168.1.254'.","Filter or reject IPv6 targets before passing them to the IP range parser.","Extend/patch the parser if IPv6 range support is required — the current implementation does not support it."],"exampleFix":"// before\nParseIPRangeString(\"2001:db8::1-2001:db8::ff\")\n// after\nParseIPRangeString(\"192.168.1.1-192.168.1.254\")","handlingStrategy":"validation","validationCode":"func isIPv4Range(start, end string) bool {\n    return net.ParseIP(start).To4() != nil && net.ParseIP(end).To4() != nil\n}","typeGuard":null,"tryCatchPattern":"ips, err := parseIPRangeString(rangeStr)\nif err != nil {\n    return fmt.Errorf(\"IPv4 required for range %q: %w\", rangeStr, err)\n}","preventionTips":["Reject or separately handle IPv6 targets before range parsing","Use net.ParseIP(...).To4() != nil as an IPv4 check in target ingestion","Document that the range parser is IPv4-only"],"tags":["ipv4","ip-range","unsupported"],"backgroundTag":"unsupported-operation","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}