Skip to content

Commit a9620e1

Browse files
authored
Merge pull request #4 from cube-root/security
added more security
2 parents b06f4d5 + a553a69 commit a9620e1

10 files changed

Lines changed: 415 additions & 109 deletions

File tree

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ curl -H "X-Proxy-Token: mysecrettoken" https://your-tunnel.proxyhub.cloud/
127127
| `-t, --token <token>` | Token for tunnel protection |
128128
| `-i, --inspect` | Enable request inspector UI |
129129
| `--inspect-port <port>` | Port for inspector UI (default: port + 1000) |
130+
| `-k, --auth-key <key>` | Authentication key for the ProxyHub server |
130131
| `-d, --debug` | Enable debug mode |
131132
| `-V, --version` | Output version number |
132133
| `-h, --help` | Display help |
@@ -182,6 +183,11 @@ PROXYHUB_SOCKET_URL=https://your-server.com proxyhub -p 3000
182183
| `PROTOCOL` | `https` | Protocol for generated URLs |
183184
| `SOCKET_PATH` | `/socket.io` | Socket.IO path |
184185
| `CONNECTION_TIMEOUT_MINUTES` | `30` | Session timeout (0 = unlimited) |
186+
| `SOCKET_AUTH_KEY` | - | Shared key for socket authentication |
187+
| `ALLOWED_ORIGINS` | - | Comma-separated list of allowed CORS origins |
188+
| `RATE_LIMIT_WINDOW_MS` | `600000` | HTTP rate limit window (ms) |
189+
| `RATE_LIMIT_MAX_REQUESTS` | `5000` | Max HTTP requests per window |
190+
| `SOCKET_MAX_CONNECTIONS_PER_MINUTE` | `30` | Max socket connections per IP per minute |
185191

186192
### Client
187193

@@ -190,6 +196,8 @@ PROXYHUB_SOCKET_URL=https://your-server.com proxyhub -p 3000
190196
| `PROXYHUB_SOCKET_URL` | `https://connect.proxyhub.cloud` | ProxyHub server URL |
191197
| `PROXYHUB_SOCKET_PATH` | `/socket.io` | Socket.IO path |
192198
| `PROXYHUB_TOKEN` | - | Token for tunnel protection |
199+
| `PROXYHUB_AUTH_KEY` | - | Authentication key for the server |
200+
| `PROXYHUB_ALLOW_INSECURE` | - | Allow self-signed TLS certificates |
193201

194202
## How It Works
195203

@@ -206,6 +214,20 @@ Internet Request Your Local Server
206214
(proxyhub.cloud) (your machine)
207215
```
208216

217+
## Security
218+
219+
ProxyHub includes several security features for production use:
220+
221+
- **Socket authentication** — set `SOCKET_AUTH_KEY` on the server and `--auth-key` on the client to restrict connections
222+
- **TLS verification** — enabled by default; opt out with `PROXYHUB_ALLOW_INSECURE` for self-signed certs
223+
- **Rate limiting** — HTTP (5000 requests/10 min) and WebSocket (30 connections/min per IP) rate limits protect against abuse
224+
- **CORS restrictions** — configure `ALLOWED_ORIGINS` to restrict cross-origin access
225+
- **Security headers** — helmet middleware sets secure HTTP response headers
226+
- **Header filtering** — hop-by-hop headers are stripped from proxied requests
227+
- **Unpredictable tunnel IDs** — cryptographically random tunnel URLs
228+
229+
See [SECURITY.md](SECURITY.md) for full details, configuration options, and the list of fixed security issues.
230+
209231
## Development
210232

211233
```bash

SECURITY.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Security
2+
3+
ProxyHub takes security seriously. This document describes the security features available, known issues that have been addressed, and how to configure security options.
4+
5+
## Security Features
6+
7+
### Socket.IO Authentication
8+
9+
Restrict which clients can connect to your ProxyHub server by setting a shared authentication key.
10+
11+
**Server:**
12+
13+
```bash
14+
SOCKET_AUTH_KEY=your-secret-key node dist/index.js
15+
```
16+
17+
**Client:**
18+
19+
```bash
20+
proxyhub -p 3000 --auth-key your-secret-key
21+
22+
# Or via environment variable
23+
PROXYHUB_AUTH_KEY=your-secret-key proxyhub -p 3000
24+
```
25+
26+
When `SOCKET_AUTH_KEY` is set on the server, only clients providing the matching key can establish a tunnel. When unset, any client can connect (backward compatible).
27+
28+
Authentication uses `crypto.timingSafeEqual` to prevent timing attacks.
29+
30+
### TLS Certificate Verification
31+
32+
The client enforces TLS certificate verification by default. To allow self-signed certificates (e.g., in development), set:
33+
34+
```bash
35+
PROXYHUB_ALLOW_INSECURE=1 proxyhub -p 3000
36+
```
37+
38+
### CORS Restrictions
39+
40+
**Server:** Restrict allowed origins for HTTP and WebSocket connections:
41+
42+
```bash
43+
ALLOWED_ORIGINS=https://example.com,https://app.example.com node dist/index.js
44+
```
45+
46+
When unset, all origins are allowed (backward compatible).
47+
48+
**Inspector:** The inspector UI only accepts CORS requests from `localhost` and `127.0.0.1`.
49+
50+
### Token Protection
51+
52+
Secure individual tunnels with per-tunnel tokens:
53+
54+
```bash
55+
proxyhub -p 3000 --token mysecrettoken
56+
```
57+
58+
Requests must include the `X-Proxy-Token` header. See the main [README](README.md#token-protection) for details.
59+
60+
### Rate Limiting
61+
62+
**HTTP requests** are rate-limited by default (5000 requests per 10-minute window per IP). The `/status` and `/health` endpoints are excluded.
63+
64+
**Socket.IO connections** are limited to 30 connections per minute per IP.
65+
66+
Configure via environment variables:
67+
68+
| Variable | Default | Description |
69+
|----------|---------|-------------|
70+
| `RATE_LIMIT_WINDOW_MS` | `600000` (10 min) | HTTP rate limit window in milliseconds |
71+
| `RATE_LIMIT_MAX_REQUESTS` | `100` | Max HTTP requests per window per IP |
72+
| `SOCKET_MAX_CONNECTIONS_PER_MINUTE` | `10` | Max socket connections per minute per IP |
73+
74+
### Security Headers
75+
76+
The server uses [helmet](https://helmetjs.github.io/) to set secure HTTP headers including Content-Security-Policy, X-Content-Type-Options, X-Frame-Options, and others.
77+
78+
### Request Body Limits
79+
80+
The server limits request bodies to 10 MB to prevent denial-of-service via oversized payloads.
81+
82+
### Header Filtering
83+
84+
Hop-by-hop headers (`Transfer-Encoding`, `Connection`, `Keep-Alive`, `Upgrade`, `TE`, `Trailer`, `Proxy-Authenticate`, `Proxy-Authorization`) are stripped from proxied requests to prevent header injection and protocol confusion attacks.
85+
86+
### Unpredictable Tunnel IDs
87+
88+
Tunnel IDs are generated using `crypto.randomBytes(16)` (32-character hex strings) instead of deterministic hashes. IDs are persisted in `~/.proxyhub/tunnel-ids.json` for stability across restarts while remaining unpredictable to attackers.
89+
90+
## Fixed Security Issues
91+
92+
| ID | Severity | Issue | Fix |
93+
|----|----------|-------|-----|
94+
| H8 | High | Vulnerable dependencies | Updated dependencies via `npm audit fix` |
95+
| H4 | High | Hop-by-hop headers forwarded to tunnels | Headers are now stripped before forwarding |
96+
| H3 | High | No request body size limit | Added 10 MB limit on JSON and URL-encoded bodies |
97+
| H1 | High | No rate limiting | Added HTTP and Socket.IO rate limiting |
98+
| C1 | Critical | No socket authentication | Added opt-in shared-key authentication with timing-safe comparison |
99+
| C2 | Critical | TLS certificate verification disabled | Enabled by default; opt-out via `PROXYHUB_ALLOW_INSECURE` |
100+
| C3 | Critical | Predictable tunnel IDs | Replaced MD5-based IDs with cryptographically random IDs |
101+
| C4 | Critical | Unrestricted CORS | Server respects `ALLOWED_ORIGINS`; inspector restricted to localhost |
102+
| M3 | Medium | Missing security headers | Added helmet middleware |
103+
104+
## Environment Variables Reference
105+
106+
### Server
107+
108+
| Variable | Default | Description |
109+
|----------|---------|-------------|
110+
| `SOCKET_AUTH_KEY` | unset (no auth) | Shared key for socket authentication |
111+
| `ALLOWED_ORIGINS` | unset (allow all) | Comma-separated list of allowed CORS origins |
112+
| `RATE_LIMIT_WINDOW_MS` | `600000` | HTTP rate limit window (ms) |
113+
| `RATE_LIMIT_MAX_REQUESTS` | `5000` | Max HTTP requests per window |
114+
| `SOCKET_MAX_CONNECTIONS_PER_MINUTE` | `30` | Max socket connections per IP per minute |
115+
116+
### Client
117+
118+
| Variable | Default | Description |
119+
|----------|---------|-------------|
120+
| `PROXYHUB_AUTH_KEY` | unset (random) | Authentication key sent to the server |
121+
| `PROXYHUB_ALLOW_INSECURE` | unset (TLS on) | Set to allow self-signed TLS certificates |
122+
123+
## Reporting Vulnerabilities
124+
125+
If you discover a security vulnerability, please report it responsibly by opening a private issue on [GitHub](https://github.com/cube-root/proxyhub/issues) or contacting the maintainers directly. Do not disclose vulnerabilities publicly until a fix is available.

0 commit comments

Comments
 (0)