{"record":{"id":"b05ac92a88b4ee8e","repo":"larksuite/cli","slug":"official-skills-index-redirected-to-non-https-url","errorCode":null,"errorMessage":"official skills index redirected to non-HTTPS URL: %s","messagePattern":"official skills index redirected to non-HTTPS URL: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/selfupdate/updater.go","lineNumber":299,"sourceCode":"func (u *Updater) FetchSkillsIndex(source string) *NpmResult {\n\tif u.SkillsIndexFetchOverride != nil {\n\t\treturn u.SkillsIndexFetchOverride()\n\t}\n\n\tr := &NpmResult{}\n\tctx, cancel := context.WithTimeout(context.Background(), skillsIndexFetchTimeout)\n\tdefer cancel()\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, skillsIndexURL(source), nil)\n\tif err != nil {\n\t\tr.Err = err\n\t\treturn r\n\t}\n\n\tclient := transport.NewHTTPClient(0)\n\tclient.CheckRedirect = func(req *http.Request, via []*http.Request) error {\n\t\tif req.URL.Scheme != \"https\" {\n\t\t\treturn fmt.Errorf(\"official skills index redirected to non-HTTPS URL: %s\", req.URL.Redacted())\n\t\t}\n\t\treturn nil\n\t}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tr.Err = err\n\t\treturn r\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {\n\t\tr.Err = fmt.Errorf(\"official skills index returned HTTP %d\", resp.StatusCode)\n\t\treturn r\n\t}\n\n\tlimited := io.LimitReader(resp.Body, skillsIndexMaxBodySize+1)\n\tif _, err := io.Copy(&r.Stdout, limited); err != nil {\n\t\tr.Err = err","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/selfupdate/updater.go#L281-L317","documentation":"FetchSkillsIndex fetches the official skills index over HTTP with a redirect check: the CheckRedirect hook rejects any redirect whose target URL is not HTTPS. This error is returned when the server (or a man-in-the-middle) redirects the request to a non-HTTPS URL, which the client treats as a security violation and aborts.","triggerScenarios":"Calling Updater.FetchSkillsIndex(source) when the skills-index host responds with a 3xx redirect whose Location resolves to a URL with a scheme other than https (e.g. http://).","commonSituations":"Misconfigured internal mirror redirecting to plain HTTP; captive-portal or proxy rewriting redirects to http; typo'd or legacy index URL that redirects to a deprecated http endpoint; intentional downgrade attack (which this guard exists to block).","solutions":["Inspect the index URL/source being fetched and use a canonical HTTPS skills-index URL","If you control the redirect, fix the server/mirror to redirect only to https:// URLs","Bypass local proxies/captive portals that rewrite redirects to http and retry","Verify you are not pointing at a stale mirror; reconfigure the skills source to the official HTTPS index"],"exampleFix":"// before\nres := updater.FetchSkillsIndex(\"http://internal-mirror.example.com/index.json\")\n// after\nres := updater.FetchSkillsIndex(\"https://internal-mirror.example.com/index.json\")","handlingStrategy":"validation","validationCode":"u, err := url.Parse(indexURL)\nif err != nil || u.Scheme != \"https\" { /* fix the source URL before fetching */ }","typeGuard":"func isHTTPS(s string) bool { u, err := url.Parse(s); return err == nil && u.Scheme == \"https\" }","tryCatchPattern":"res := updater.FetchSkillsIndex(source)\nif res.Err != nil {\n\tif strings.Contains(res.Err.Error(), \"redirected to non-HTTPS\") {\n\t\t// reconfigure source to an HTTPS index URL\n\t} else {\n\t\treturn res.Err\n\t}\n}","preventionTips":["Always configure skills sources with https:// URLs","Audit internal mirrors so redirects keep HTTPS","Bypass proxies that rewrite redirects to plain http","Treat any http redirect as a misconfiguration or attack signal, not something to allow"],"tags":["https","redirect","security","network","selfupdate"],"backgroundTag":"insecure-redirect-blocked","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"}