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

  1. Sanitize the name to a plain base filename before calling save (strip directories)
  2. Use an allow-list pattern such as ^[A-Za-z0-9._-]+$ plus the .json suffix
  3. 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

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


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/fed836bcf9a3f3ab. Report an issue: GitHub.