Fix critical security vulnerability in amp-restrict-management-to-localhost feature where attackers could bypass localhost restriction by spoofing X-Forwarded-For headers. Changes: - Use RemoteAddr (actual TCP connection) instead of ClientIP() in localhostOnlyMiddleware to prevent header spoofing attacks - Add comprehensive test coverage for spoofing prevention (6 test cases) - Update documentation with reverse proxy deployment guidance and limitations of the RemoteAddr approach The fix prevents attacks like: curl -H "X-Forwarded-For: 127.0.0.1" https://server/api/user Trade-off: Users behind reverse proxies will need to disable the feature and use alternative security measures (firewall rules, proxy ACLs). Addresses security review feedback from PR #287.
Showing the changes to docs (1 of 3 files). Show all
Unified · Split
| @@ -135,8 +135,39 @@ When enabled, management routes (`/api/auth`, `/api/user`, `/api/threads`, etc.) · 134 unmodified lines | ||
| 135 | 135 | - Drive-by browser attacks |
| 136 | 136 | - Remote access to management endpoints |
| 137 | 137 | - CORS-based attacks |
| 138 | +- Header spoofing attacks (e.g., `X-Forwarded-For: 127.0.0.1`) | |
| 138 | 139 | |
| 139 | −**Important**: Only disable this if you understand the security implications and have other protections in place (VPN, firewall, etc.). | |
| 140 | +#### How It Works | |
| 141 | + | |
| 142 | +This restriction uses the **actual TCP connection address** (`RemoteAddr`), not HTTP headers like `X-Forwarded-For`. This prevents header spoofing attacks but has important implications: | |
| 143 | + | |
| 144 | +- ✅ **Works for direct connections**: Running CLIProxyAPI directly on your machine or server | |
| 145 | +- ⚠️ **May not work behind reverse proxies**: If deploying behind nginx, Cloudflare, or other proxies, the connection will appear to come from the proxy's IP, not localhost | |
| 146 | + | |
| 147 | +#### Reverse Proxy Deployments | |
| 148 | + | |
| 149 | +If you need to run CLIProxyAPI behind a reverse proxy (nginx, Caddy, Cloudflare Tunnel, etc.): | |
| 150 | + | |
| 151 | +1. **Disable the localhost restriction**: | |
| 152 | + ```yaml | |
| 153 | + amp-restrict-management-to-localhost: false | |
| 154 | + ``` | |
| 155 | + | |
| 156 | +2. **Use alternative security measures**: | |
| 157 | + - Firewall rules restricting access to management routes | |
| 158 | + - Proxy-level authentication (HTTP Basic Auth, OAuth) | |
| 159 | + - Network-level isolation (VPN, Tailscale, Cloudflare Access) | |
| 160 | + - Bind CLIProxyAPI to `127.0.0.1` only and access via SSH tunnel | |
| 161 | + | |
| 162 | +3. **Example nginx configuration** (blocks external access to management routes): | |
| 163 | + ```nginx | |
| 164 | + location /api/auth { deny all; } | |
| 165 | + location /api/user { deny all; } | |
| 166 | + location /api/threads { deny all; } | |
| 167 | + location /api/internal { deny all; } | |
| 168 | + ``` | |
| 169 | + | |
| 170 | +**Important**: Only disable `amp-restrict-management-to-localhost` if you understand the security implications and have other protections in place. | |
| 140 | 171 | |
| 141 | 172 | ## Setup |
| 142 | 173 | |