router-for-me/CLIProxyAPI · error
invalid auth file name
Error message
invalid auth file name
What it means
Thrown by validateHostAuthSaveRequest when the requested save name fails isUnsafeAuthFileName. That guard rejects names with path separators, traversal segments, reserved device names, and similar unsafe components, so a plugin cannot write outside the auth directory.
Source
Thrown at internal/pluginhost/auth_callbacks.go:265
if os.IsNotExist(errRead) {
return nil, nil, fmt.Errorf("auth file not found for auth_index %s", authIndex)
}
return nil, nil, fmt.Errorf("failed to read auth file: %w", errRead)
}
if len(bytesTrimSpace(data)) == 0 {
return nil, nil, fmt.Errorf("auth file is empty for auth_index %s", authIndex)
}
var metadata map[string]any
if errUnmarshal := json.Unmarshal(data, &metadata); errUnmarshal != nil {
return nil, nil, fmt.Errorf("invalid auth file for auth_index %s: %w", authIndex, errUnmarshal)
}
return auth, data, nil
}
func validateHostAuthSaveRequest(req pluginapi.HostAuthSaveRequest) (string, []byte, error) {
name := strings.TrimSpace(req.Name)
if isUnsafeAuthFileName(name) {
return "", nil, fmt.Errorf("invalid auth file name")
}
if !strings.HasSuffix(strings.ToLower(name), ".json") {
return "", nil, fmt.Errorf("auth file name must end with .json")
}
rawJSON := bytesTrimSpace(req.JSON)
if len(rawJSON) == 0 {
return "", nil, fmt.Errorf("json is required")
}
var metadata map[string]any
if errUnmarshal := json.Unmarshal(rawJSON, &metadata); errUnmarshal != nil {
return "", nil, fmt.Errorf("invalid auth json: %w", errUnmarshal)
}
return filepath.Base(name), rawJSON, nil
}
func (h *Host) saveAuthFile(ctx context.Context, name string, data []byte) (string, error) {
authDir := h.resolvedAuthDir()
if authDir == "" {View on GitHub (pinned to 78f0c4079e)
Solutions
- Sanitize the name to a plain base filename before calling save (strip directories)
- Use an allow-list pattern such as ^[A-Za-z0-9._-]+$ plus the .json suffix
- If the plugin is third-party, verify its save requests and report the non-compliant plugin
Example fix
// before
req := pluginapi.HostAuthSaveRequest{Name: filepath.Join(dir, name)} // rejected
// after
req := pluginapi.HostAuthSaveRequest{Name: filepath.Base(name)} // plain base name Defensive patterns
Strategy: validation
Validate before calling
var safeNameRe = regexp.MustCompile(`^[A-Za-z0-9._-]+\.json$`)
if !safeNameRe.MatchString(name) {
name = filepath.Base(name) // or reject outright
} Prevention
- Always derive save names from filepath.Base plus a strict allow-list
- Never interpolate user input into auth file names
When it happens
Trigger: A plugin calls the host auth-save callback with a name like ../evil.json, /etc/cron.d/x.json, .json with backslashes, or another pattern the safety check rejects.
Common situations: Plugin bug building the filename from user input or provider IDs containing slashes; a malicious or misbehaving plugin attempting path traversal; Windows-style paths submitted on a name field.
Related errors
- auth file name must end with .json
- json is required
- invalid auth json: %w
- auth path is empty
- invalid auth weight: %w
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/fed836bcf9a3f3ab.
Report an issue: GitHub.