Hi, thanks for maintaining this proxy. I noticed a default-deployment safety issue in the current main branch (a1c10357098f): proxy auth is disabled when API_KEYS is empty, while the default listen address and Docker example can expose the service.
Relevant code/docs:
server.go
57 func (s *Server) withMiddleware(next http.Handler) http.Handler {
58 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
59 if len(s.cfg.APIKeys) > 0 && !s.authorized(r) {
60 if isClaudeRequestPath(r.URL.Path) {
61 writeClaudeError(w, http.StatusUnauthorized, "invalid proxy api key", "authentication_error")
62 } else {
63 writeOpenAIError(w, http.StatusUnauthorized, "invalid proxy api key", "authentication_error", "")
64 }
65 return
66 }
67 next.ServeHTTP(w, r)
68 })
69 }
Line 59 only performs client authentication when APIKeys is non-empty. Line 67 forwards the request when the list is empty.
71 func (s *Server) authorized(r *http.Request) bool {
72 if apiKey := strings.TrimSpace(r.Header.Get("x-api-key")); apiKey != "" {
73 if containsString(s.cfg.APIKeys, apiKey) {
74 return true
75 }
76 }
78 authorization := strings.TrimSpace(r.Header.Get("Authorization"))
...
87 return containsString(s.cfg.APIKeys, apiKey)
88 }
Lines 71-88 implement client-key validation, but that validation is bypassed by the empty-API_KEYS default above.
94 func (s *Server) handleHealthz(w http.ResponseWriter, r *http.Request) {
...
100 response := map[string]any{
101 "ok": true,
102 "started_at": s.started.UTC(),
103 "uptime_sec": int(time.Since(s.started).Seconds()),
104 "token_state": s.runs.Snapshots(),
105 }
Lines 100-104 expose operational token-pool state through /healthz under the same auth boundary.
config.go
105 func loadRawConfig(configPath string) (rawConfig, error) {
106 cfg := rawConfig{
107 ListenAddr: ":8080",
108 UpstreamBaseURL: "https://www.codebuff.com",
109 RotationInterval: "6h",
110 RequestTimeout: "15m",
111 }
Line 107 defaults the proxy to listen on :8080, not loopback-only.
README.md
77 | `LISTEN_ADDR` | Proxy listen address (default `:8080`) |
79 | `AUTH_TOKENS` | Freebuff auth tokens (JSON array or comma-separated env var) |
82 | `API_KEYS` | Client API keys for proxy auth (empty = open access) |
The docs explicitly state that empty API_KEYS means open access.
94 docker run -d --name Freebuff2API \
95 -p 8080:8080 \
96 -e AUTH_TOKENS="token1,token2" \
97 ghcr.io/quorinex/freebuff2api:latest
The Docker example publishes the service and configures upstream auth tokens, but does not configure client API_KEYS.
Why this matters:
The proxy holds Freebuff AUTH_TOKENS and turns them into OpenAI-compatible and Anthropic-compatible endpoints. A user following the Docker example on a VPS, NAS, or cloud machine may accidentally expose an unauthenticated relay. Anyone who can reach the port can consume the configured upstream tokens/accounts, increasing waiting-room pressure, quota/rate-limit exhaustion, and account-ban risk.
Suggested direction:
- Require
API_KEYS by default when LISTEN_ADDR is not loopback, or fail startup unless an explicit ALLOW_OPEN_ACCESS=true or --allow-open-access is set.
- Update the Docker example to include
API_KEYS.
- Print a prominent startup warning when auth is disabled and the listen address is public.
Hi, thanks for maintaining this proxy. I noticed a default-deployment safety issue in the current main branch (
a1c10357098f): proxy auth is disabled whenAPI_KEYSis empty, while the default listen address and Docker example can expose the service.Relevant code/docs:
server.goLine 59 only performs client authentication when
APIKeysis non-empty. Line 67 forwards the request when the list is empty.Lines 71-88 implement client-key validation, but that validation is bypassed by the empty-
API_KEYSdefault above.Lines 100-104 expose operational token-pool state through
/healthzunder the same auth boundary.config.goLine 107 defaults the proxy to listen on
:8080, not loopback-only.README.mdThe docs explicitly state that empty
API_KEYSmeans open access.94 docker run -d --name Freebuff2API \ 95 -p 8080:8080 \ 96 -e AUTH_TOKENS="token1,token2" \ 97 ghcr.io/quorinex/freebuff2api:latestThe Docker example publishes the service and configures upstream auth tokens, but does not configure client
API_KEYS.Why this matters:
The proxy holds Freebuff
AUTH_TOKENSand turns them into OpenAI-compatible and Anthropic-compatible endpoints. A user following the Docker example on a VPS, NAS, or cloud machine may accidentally expose an unauthenticated relay. Anyone who can reach the port can consume the configured upstream tokens/accounts, increasing waiting-room pressure, quota/rate-limit exhaustion, and account-ban risk.Suggested direction:
API_KEYSby default whenLISTEN_ADDRis not loopback, or fail startup unless an explicitALLOW_OPEN_ACCESS=trueor--allow-open-accessis set.API_KEYS.