{"record":{"id":"a37db0833cff1659","repo":"router-for-me/CLIProxyAPI","slug":"plugin-store-url-contains-sensitive-query-paramete","errorCode":null,"errorMessage":"plugin store url contains sensitive query parameter","messagePattern":"plugin store url contains sensitive query parameter","errorType":"http","errorClass":null,"httpStatus":502,"severity":"error","filePath":"internal/pluginstore/auth.go","lineNumber":319,"sourceCode":"\t\t\treturn false, fmt.Errorf(\"plugin store resolved auth header value is empty\")\n\t\t}\n\t\theaders.Set(item.HeaderName, string(item.HeaderValue))\n\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","sourceCodeStart":301,"sourceCodeEnd":337,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginstore/auth.go#L301-L337","documentation":"hasSensitiveQueryParameter detected a query parameter in the store URL whose name looks like credential material (e.g. token, api_key, signature patterns). validatePluginStoreRequestURL blocks this because secrets in query strings get recorded in proxies, access logs, and caches. Authentication material must go through the auth rules instead of the URL.","triggerScenarios":"A store URL containing ?token=..., ?api_key=..., ?access_token=... (or similar sensitive names) is used for a registry/metadata/artifact fetch.","commonSituations":"Copy-pasting a pre-signed or personal URL from a vendor dashboard; custom store that documents token-in-query auth; older config carried over after this hardening check was introduced.","solutions":["Strip the sensitive query parameter from the URL","Move the secret into an auth rule (type: bearer with token-env, or header) matching that store","If the parameter is genuinely non-sensitive, rename it to something not on the sensitive list"],"exampleFix":"# before\nurl: https://plugins.example.com/index.json?api_key=sk-123\n\n# after\nurl: https://plugins.example.com/index.json\nauth:\n  - match: https://plugins.example.com\n    type: bearer\n    token-env: PLUGIN_API_KEY","handlingStrategy":"validation","validationCode":"func urlHasSensitiveQuery(raw string) bool {\n\tu, err := url.Parse(strings.TrimSpace(raw))\n\tif err != nil {\n\t\treturn false\n\t}\n\tfor k := range u.Query() {\n\t\tlk := strings.ToLower(k)\n\t\tif strings.Contains(lk, \"token\") || strings.Contains(lk, \"key\") || strings.Contains(lk, \"secret\") || strings.Contains(lk, \"signature\") {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Put auth material in auth rules (bearer/header), never in store URL query strings","Audit store URLs for pre-signed links before committing them to config"],"tags":["security","url","plugin-store","auth"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}