{"record":{"id":"f408b55c6be52251","repo":"router-for-me/CLIProxyAPI","slug":"insecure-plugin-store-url-requires-matching-allow","errorCode":null,"errorMessage":"insecure plugin store url requires matching allow-insecure auth rule","messagePattern":"insecure plugin store url requires matching allow-insecure auth rule","errorType":"http","errorClass":null,"httpStatus":502,"severity":"error","filePath":"internal/pluginstore/auth.go","lineNumber":322,"sourceCode":"\tdefault:\n\t\treturn false, fmt.Errorf(\"unsupported plugin store resolved auth type %q\", item.Type)\n\t}\n\treturn true, nil\n}\n\nfunc validatePluginStoreRequestURL(auth []AuthConfig, requestURL string, kind string) error {\n\tparsed, errParse := url.Parse(strings.TrimSpace(requestURL))\n\tif errParse != nil || parsed.Scheme == \"\" || parsed.Host == \"\" {\n\t\treturn fmt.Errorf(\"invalid plugin store url\")\n\t}\n\tif parsed.User != nil {\n\t\treturn fmt.Errorf(\"plugin store url must not contain credentials\")\n\t}\n\tif hasSensitiveQueryParameter(parsed) {\n\t\treturn fmt.Errorf(\"plugin store url contains sensitive query parameter\")\n\t}\n\tif strings.EqualFold(parsed.Scheme, \"http\") && !allowInsecurePluginStoreURL(auth, requestURL, kind) {\n\t\treturn fmt.Errorf(\"insecure plugin store url requires matching allow-insecure auth rule\")\n\t}\n\treturn nil\n}\n\nfunc allowInsecurePluginStoreURL(auth []AuthConfig, requestURL string, kind string) bool {\n\titem, ok := matchingAuthConfig(auth, requestURL, kind)\n\treturn ok && item.AllowInsecure\n}\n\nfunc validateResolvedAuthExpiry(auth []ResolvedAuthConfig, expiresAt time.Time, now time.Time, requestURL string, kind string) error {\n\tif expiresAt.IsZero() {\n\t\treturn nil\n\t}\n\tif _, ok := matchingResolvedAuthConfig(auth, requestURL, kind); !ok {\n\t\treturn nil\n\t}\n\tif !now.Before(expiresAt) {\n\t\treturn fmt.Errorf(\"plugin store resolved auth expired\")","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginstore/auth.go#L304-L340","documentation":"The store URL uses plain http:// and no matching auth rule has allow-insecure: true. Because cleartext downloads of plugin artifacts are tamperable, pluginstore gates http URLs behind an explicit per-rule opt-in: allowInsecurePluginStoreURL only returns true when a rule matching this URL and request kind carries AllowInsecure. Otherwise the fetch is refused.","triggerScenarios":"Fetching a registry/metadata/artifact over http:// (e.g. http://localhost:8080/registry.json or an internal mirror) where the matching auth rule lacks allow-insecure, or no rule matches at all.","commonSituations":"Local development server without TLS; internal corporate mirror on http; adding a new http store URL but forgetting the flag; match pattern does not cover the URL so the allow-insecure rule never matches.","solutions":["Prefer switching the store to https:// (add TLS or a local cert) — the only fully supported option","For trusted internal/dev use, set allow-insecure: true on an auth rule whose match covers the URL and whose apply-to includes the request kind","Verify the match pattern actually matches the URL (scheme+host prefix) — a non-matching rule will not authorize the insecure fetch"],"exampleFix":"# before\n- match: http://localhost:8080\n  type: none\n\n# after\n- match: http://localhost:8080\n  type: none\n  allow-insecure: true","handlingStrategy":"validation","validationCode":"func insecureAllowed(rules []AuthConfig, requestURL, kind string) bool {\n\tu, _ := url.Parse(strings.TrimSpace(requestURL))\n\tif u == nil || !strings.EqualFold(u.Scheme, \"http\") {\n\t\treturn true // not insecure\n\t}\n\tfor _, r := range rules {\n\t\tif r.AllowInsecure && pluginStoreURLMatchesAuthRule(requestURL, r.Match) && authAppliesTo(r, kind) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default store endpoints to https; reserve allow-insecure: true for loopback/dev and pair it with a tight match pattern","Document every allow-insecure rule so the security exception is reviewable"],"tags":["security","config","plugin-store","tls"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}