{"record":{"id":"816eb04c24933ade","repo":"larksuite/cli","slug":"only-http-https-urls-are-supported","errorCode":null,"errorMessage":"only http/https URLs are supported","messagePattern":"only http/https URLs are supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/validate/url.go","lineNumber":87,"sourceCode":"\t}\n\tip16 := ip.To16()\n\tif ip16 == nil {\n\t\treturn true\n\t}\n\tif ip16[0]&0xfe == 0xfc { // fc00::/7 unique local address\n\t\treturn true\n\t}\n\treturn false\n}\n\n// ValidateDownloadSourceURL validates a download URL and blocks local/internal targets.\nfunc ValidateDownloadSourceURL(ctx context.Context, rawURL string) error {\n\tu, err := url.Parse(rawURL)\n\tif err != nil || u == nil {\n\t\treturn fmt.Errorf(\"invalid URL\")\n\t}\n\tif u.Scheme != \"http\" && u.Scheme != \"https\" {\n\t\treturn fmt.Errorf(\"only http/https URLs are supported\")\n\t}\n\t_, err = resolveDownloadHost(ctx, u.Hostname(), net.DefaultResolver.LookupIP)\n\treturn err\n}\n\ntype downloadLookupIPFunc func(context.Context, string, string) ([]net.IP, error)\n\nfunc resolveDownloadHost(ctx context.Context, rawHost string, lookupIP downloadLookupIPFunc) ([]net.IP, error) {\n\thost := strings.TrimSpace(strings.ToLower(rawHost))\n\tif host == \"\" {\n\t\treturn nil, fmt.Errorf(\"URL host is required\")\n\t}\n\tif host == \"localhost\" || strings.HasSuffix(host, \".localhost\") {\n\t\treturn nil, fmt.Errorf(\"local/internal host is not allowed\")\n\t}\n\tif ip := net.ParseIP(host); ip != nil {\n\t\tif isRestrictedDownloadIP(ip) {\n\t\t\treturn nil, fmt.Errorf(\"local/internal host is not allowed\")","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/validate/url.go#L69-L105","documentation":"After parsing, ValidateDownloadSourceURL requires the scheme to be http or https; any other scheme (file:, ftp:, data:, etc.) is rejected with this message. This confines downloads to web URLs and blocks local-file or non-HTTP access vectors. DNS/SSRF checks run only after this gate passes.","triggerScenarios":"ValidateDownloadSourceURL receives a parsed URL whose u.Scheme is not \"http\" or \"https\" — e.g. file:///etc/passwd, ftp://host/file, or a data: URL.","commonSituations":"Attempting to download local files via file:// URLs, pointing the download command at FTP mirrors, or doc image sources that reference non-HTTP protocols.","solutions":["Use an https:// (or http://) URL for the source.","For local files, read them directly instead of routing through the download command.","Download via FTP/other protocols with a dedicated tool first, then process the local file.","If the source is a doc image, ensure the exported link is an HTTP(S) URL."],"exampleFix":"// before\nlark-cli download url \"file:///tmp/report.pdf\"\n// after\ncp /tmp/report.pdf /destination/   # local files don't go through download url\n# or: lark-cli download url \"https://example.com/report.pdf\"","handlingStrategy":"validation","validationCode":"u, _ := url.Parse(rawURL)\nif u == nil || (u.Scheme != \"http\" && u.Scheme != \"https\") {\n    return fmt.Errorf(\"use an http/https URL\")\n}","typeGuard":null,"tryCatchPattern":"if err := validate.ValidateDownloadSourceURL(ctx, raw); err != nil {\n    if strings.Contains(err.Error(), \"only http/https\") {\n        return fmt.Errorf(\"download source must be http/https; handle this source separately: %w\", err)\n    }\n    return err\n}","preventionTips":["Only pass web URLs to download commands; use file tools for local files.","Convert ftp:// or other scheme sources with a dedicated tool first.","Whitelist http/https at your own input boundary before invoking the CLI.","Beware crafted links using data:/file: schemes in untrusted content."],"tags":["input-validation","url","security","ssrf"],"backgroundTag":"unsupported-url-scheme","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}