router-for-me/CLIProxyAPI · error
plugin store url contains sensitive query parameter
Error message
plugin store url contains sensitive query parameter
What it means
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.
Source
Thrown at internal/pluginstore/auth.go:319
return false, fmt.Errorf("plugin store resolved auth header value is empty")
}
headers.Set(item.HeaderName, string(item.HeaderValue))
default:
return false, fmt.Errorf("unsupported plugin store resolved auth type %q", item.Type)
}
return true, nil
}
func validatePluginStoreRequestURL(auth []AuthConfig, requestURL string, kind string) error {
parsed, errParse := url.Parse(strings.TrimSpace(requestURL))
if errParse != nil || parsed.Scheme == "" || parsed.Host == "" {
return fmt.Errorf("invalid plugin store url")
}
if parsed.User != nil {
return fmt.Errorf("plugin store url must not contain credentials")
}
if hasSensitiveQueryParameter(parsed) {
return fmt.Errorf("plugin store url contains sensitive query parameter")
}
if strings.EqualFold(parsed.Scheme, "http") && !allowInsecurePluginStoreURL(auth, requestURL, kind) {
return fmt.Errorf("insecure plugin store url requires matching allow-insecure auth rule")
}
return nil
}
func allowInsecurePluginStoreURL(auth []AuthConfig, requestURL string, kind string) bool {
item, ok := matchingAuthConfig(auth, requestURL, kind)
return ok && item.AllowInsecure
}
func validateResolvedAuthExpiry(auth []ResolvedAuthConfig, expiresAt time.Time, now time.Time, requestURL string, kind string) error {
if expiresAt.IsZero() {
return nil
}
if _, ok := matchingResolvedAuthConfig(auth, requestURL, kind); !ok {
return nilView on GitHub (pinned to 78f0c4079e)
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
Example fix
# before
url: https://plugins.example.com/index.json?api_key=sk-123
# after
url: https://plugins.example.com/index.json
auth:
- match: https://plugins.example.com
type: bearer
token-env: PLUGIN_API_KEY Defensive patterns
Strategy: validation
Validate before calling
func urlHasSensitiveQuery(raw string) bool {
u, err := url.Parse(strings.TrimSpace(raw))
if err != nil {
return false
}
for k := range u.Query() {
lk := strings.ToLower(k)
if strings.Contains(lk, "token") || strings.Contains(lk, "key") || strings.Contains(lk, "secret") || strings.Contains(lk, "signature") {
return true
}
}
return false
} Prevention
- 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
When it happens
Trigger: A store URL containing ?token=..., ?api_key=..., ?access_token=... (or similar sensitive names) is used for a registry/metadata/artifact fetch.
Common situations: 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.
Related errors
- plugin store url must not contain credentials
- xai device token: create request: %w
- invalid auth file name
- plugin store auth missing header-name
- unsupported plugin store auth type %q
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/a37db0833cff1659.
Report an issue: GitHub.