uplink-cli 0.1.29 → 0.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/SECURITY_ASSESSMENT.md +230 -0
- package/docs/SECURITY_PHASE2.md +169 -0
- package/package.json +1 -1
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# Security Assessment: Phase 1 & Recommendations
|
|
2
|
+
|
|
3
|
+
**Last Updated:** January 2025
|
|
4
|
+
**Phase 1 Status:** ✅ Completed and deployed
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 🔒 Phase 1 Security Improvements
|
|
9
|
+
|
|
10
|
+
### 1. **Hardened On-Demand TLS Endpoint** (`/internal/allow-tls`)
|
|
11
|
+
- ✅ **Secret Protection**: Requires `RELAY_INTERNAL_SECRET` (header or query param)
|
|
12
|
+
- ✅ **Hostname Validation**: Validates token format (`/^[a-zA-Z0-9]{3,64}$/`) and alias format (`ALIAS_REGEX`)
|
|
13
|
+
- ✅ **Reserved Alias Protection**: Blocks reserved aliases (`www`, `api`, `x`, `t`, etc.)
|
|
14
|
+
- ✅ **Database Verification**: Checks token/alias existence before allowing TLS issuance
|
|
15
|
+
- ✅ **Rate Limiting**: 120 requests/minute per IP (prevents enumeration/DoS)
|
|
16
|
+
|
|
17
|
+
### 2. **System Diagnostics** (`/v1/admin/system/status`)
|
|
18
|
+
- ✅ **Configuration Visibility**: Detects missing `RELAY_INTERNAL_SECRET`
|
|
19
|
+
- ✅ **Relay Health Check**: Verifies relay connectivity and connection count
|
|
20
|
+
- ✅ **TLS Mode Detection**: Reports DNS-01 wildcard vs on-demand TLS status
|
|
21
|
+
- ✅ **No Secret Exposure**: Returns only boolean flags, never raw secrets
|
|
22
|
+
|
|
23
|
+
### 3. **Production Security Enforcement**
|
|
24
|
+
- ✅ **Required Secrets**: Production fails to start without `RELAY_INTERNAL_SECRET` and `CONTROL_PLANE_TOKEN_PEPPER`
|
|
25
|
+
- ✅ **Token Hashing**: Uses HMAC-SHA256 with server-side pepper (prevents offline brute-force if DB leaks)
|
|
26
|
+
- ✅ **Environment Isolation**: Systemd services load secrets from `.env` file
|
|
27
|
+
|
|
28
|
+
### 4. **Caddy Integration**
|
|
29
|
+
- ✅ **On-Demand TLS Ask Block**: Caddy validates hosts via backend before issuing certs
|
|
30
|
+
- ✅ **Rate Limits**: `interval 2m`, `burst 5` prevents certificate spam
|
|
31
|
+
- ✅ **Primary Fallback**: DNS-01 wildcard remains primary; on-demand is optional enhancement
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## ✅ Existing Security Measures (Pre-Phase 1)
|
|
36
|
+
|
|
37
|
+
### Authentication & Authorization
|
|
38
|
+
- ✅ **Token-Based Auth**: Bearer tokens with role-based access control (admin/user)
|
|
39
|
+
- ✅ **Token Revocation**: Tokens can be revoked and expire
|
|
40
|
+
- ✅ **Audit Logging**: All auth attempts logged (success/failure with IP)
|
|
41
|
+
- ✅ **Break-Glass Admin**: `ADMIN_TOKENS` env var for emergency access (deprecated in favor of DB tokens)
|
|
42
|
+
|
|
43
|
+
### Rate Limiting
|
|
44
|
+
- ✅ **API Routes**: 100 requests/15min per IP
|
|
45
|
+
- ✅ **Auth Endpoints**: 10 attempts/15min per IP
|
|
46
|
+
- ✅ **Token Creation**: 20/hour per IP
|
|
47
|
+
- ✅ **Tunnel Creation**: 50/hour per IP
|
|
48
|
+
- ✅ **Signup**: 5/hour per IP (strictest)
|
|
49
|
+
|
|
50
|
+
### Input Validation
|
|
51
|
+
- ✅ **Schema Validation**: Zod-based validation middleware
|
|
52
|
+
- ✅ **SQL Injection Protection**: Parameterized queries (via `pool.query()`)
|
|
53
|
+
- ✅ **Alias Validation**: Regex + reserved name checks
|
|
54
|
+
- ✅ **Port Validation**: Numeric range checks
|
|
55
|
+
|
|
56
|
+
### HTTP Security
|
|
57
|
+
- ✅ **Helmet.js**: Security headers (X-Content-Type-Options, X-Frame-Options, HSTS, etc.)
|
|
58
|
+
- ✅ **Body Size Limits**: 10MB max request body
|
|
59
|
+
- ✅ **Compression**: Gzip/deflate with threshold
|
|
60
|
+
- ✅ **CORS**: Configured for public endpoints only
|
|
61
|
+
|
|
62
|
+
### Infrastructure
|
|
63
|
+
- ✅ **HTTPS Only**: Caddy enforces TLS (DNS-01 wildcard certs)
|
|
64
|
+
- ✅ **Secret Scanning**: GitHub Actions scans for committed secrets
|
|
65
|
+
- ✅ **Error Handling**: Generic error messages (no stack traces in production)
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## ⚠️ Remaining Security Gaps & Recommendations
|
|
70
|
+
|
|
71
|
+
### 🔴 High Priority
|
|
72
|
+
|
|
73
|
+
#### 1. **Internal Communication Not Encrypted** ✅ Partially Addressed
|
|
74
|
+
**Issue**: Backend ↔ Relay communication is HTTP (not HTTPS) on localhost
|
|
75
|
+
**Risk**: If localhost is compromised, internal secrets could be intercepted
|
|
76
|
+
**Status**: ✅ **Request signing middleware implemented** (optional, can be enabled)
|
|
77
|
+
**Remaining Work**:
|
|
78
|
+
- Use HTTPS with self-signed certs for internal communication (future)
|
|
79
|
+
- Or use Unix domain sockets with file permissions (future)
|
|
80
|
+
- ✅ Request signing (HMAC) middleware available but not enforced (for Caddy compatibility)
|
|
81
|
+
|
|
82
|
+
#### 2. **Token Enumeration via `/internal/allow-tls`** ✅ Improved
|
|
83
|
+
**Issue**: Even with rate limiting, attackers can enumerate valid tokens by probing hostnames
|
|
84
|
+
**Risk**: Discover active tunnel tokens
|
|
85
|
+
**Status**: ✅ **Rate limit reduced from 120/min to 60/min**
|
|
86
|
+
**Status**: ✅ **IP allowlist added** (defaults to localhost only, configurable via `INTERNAL_IP_ALLOWLIST`)
|
|
87
|
+
**Remaining Work**:
|
|
88
|
+
- Consider progressive delays after failed attempts (future enhancement)
|
|
89
|
+
|
|
90
|
+
#### 3. **Secret in Query String** ✅ Improved
|
|
91
|
+
**Issue**: `RELAY_INTERNAL_SECRET` can be passed in query string (for Caddy compatibility)
|
|
92
|
+
**Risk**: May appear in logs, browser history, referrer headers
|
|
93
|
+
**Status**: ✅ **Secrets now redacted in logs** (query params, headers automatically sanitized)
|
|
94
|
+
**Remaining Work**:
|
|
95
|
+
- Prefer header-only in future (requires Caddy module support)
|
|
96
|
+
|
|
97
|
+
### 🟡 Medium Priority
|
|
98
|
+
|
|
99
|
+
#### 4. **No Request Timeouts** ✅ Fixed
|
|
100
|
+
**Issue**: Long-running requests can tie up server resources
|
|
101
|
+
**Risk**: DoS via slow requests
|
|
102
|
+
**Status**: ✅ **Request timeout middleware added** (30 seconds default, 5 minutes for long operations)
|
|
103
|
+
**Implementation**: `backend/src/middleware/timeout.ts`
|
|
104
|
+
|
|
105
|
+
#### 5. **No Token Rotation Enforcement** ✅ Improved
|
|
106
|
+
**Issue**: Tokens can be long-lived without forced rotation
|
|
107
|
+
**Risk**: Compromised tokens remain valid indefinitely
|
|
108
|
+
**Status**: ✅ **Max token lifetime enforced** (90 days default, configurable via `MAX_TOKEN_LIFETIME_DAYS`)
|
|
109
|
+
**Status**: ✅ **Hard limit of 365 days** (never exceed 1 year)
|
|
110
|
+
**Remaining Work**:
|
|
111
|
+
- Add `uplink token rotate` command (future)
|
|
112
|
+
- Warn users when tokens approach expiry (future)
|
|
113
|
+
|
|
114
|
+
#### 6. **No IP Allowlisting for Internal Endpoints** ✅ Fixed
|
|
115
|
+
**Issue**: Internal endpoints rely solely on secret, not source IP
|
|
116
|
+
**Risk**: If secret leaks, any IP can access internal endpoints
|
|
117
|
+
**Status**: ✅ **IP allowlist middleware added** (defaults to localhost, configurable via `INTERNAL_IP_ALLOWLIST`)
|
|
118
|
+
**Implementation**: `backend/src/middleware/ip-allowlist.ts`
|
|
119
|
+
**Usage**: Supports IP addresses and CIDR ranges (e.g., `127.0.0.1,10.0.0.0/8`)
|
|
120
|
+
|
|
121
|
+
#### 7. **No Request Signing for Internal Endpoints** ✅ Implemented (Optional)
|
|
122
|
+
**Issue**: Internal endpoints use simple secret comparison
|
|
123
|
+
**Risk**: Replay attacks if secret is intercepted
|
|
124
|
+
**Status**: ✅ **HMAC request signing middleware implemented** (optional, not enforced for Caddy compatibility)
|
|
125
|
+
**Implementation**: `backend/src/middleware/request-signing.ts`
|
|
126
|
+
**Note**: Can be enabled for relay-to-backend communication, but Caddy may not support custom headers
|
|
127
|
+
|
|
128
|
+
### 🟢 Low Priority
|
|
129
|
+
|
|
130
|
+
#### 8. **No CSRF Protection**
|
|
131
|
+
**Issue**: API-only service, but no explicit CSRF tokens
|
|
132
|
+
**Risk**: Low (APIs typically don't need CSRF), but worth noting
|
|
133
|
+
**Status**: Not needed for API-only service
|
|
134
|
+
**Recommendation**: Add CSRF tokens if web UI is added
|
|
135
|
+
|
|
136
|
+
#### 9. **No Per-Endpoint Request Size Limits** ✅ Fixed
|
|
137
|
+
**Issue**: Global 10MB limit may be too large for some endpoints
|
|
138
|
+
**Risk**: Memory exhaustion on large uploads
|
|
139
|
+
**Status**: ✅ **Per-endpoint body size limits added**
|
|
140
|
+
**Implementation**: `backend/src/middleware/body-size.ts`
|
|
141
|
+
**Usage**: Tunnel creation limited to 1MB, other endpoints can use `small` (1MB), `medium` (5MB), or `large` (50MB)
|
|
142
|
+
|
|
143
|
+
#### 10. **No Account Lockout**
|
|
144
|
+
**Issue**: Rate limiting prevents brute force, but no progressive delays
|
|
145
|
+
**Risk**: Determined attackers can still attempt over long periods
|
|
146
|
+
**Recommendation**: Add exponential backoff after repeated failures
|
|
147
|
+
|
|
148
|
+
#### 11. **Dev Token Still Available**
|
|
149
|
+
**Issue**: `AGENTCLOUD_TOKEN_DEV` works in SQLite mode
|
|
150
|
+
**Risk**: Low (dev-only), but could be accidentally enabled in production
|
|
151
|
+
**Recommendation**: Remove dev token support or require explicit `NODE_ENV=development`
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## 📊 Security Posture Summary
|
|
156
|
+
|
|
157
|
+
| Category | Status | Notes |
|
|
158
|
+
|----------|--------|-------|
|
|
159
|
+
| **Authentication** | ✅ Strong | Token hashing with pepper, revocation, expiry |
|
|
160
|
+
| **Authorization** | ✅ Good | Role-based access control, admin/user separation |
|
|
161
|
+
| **Rate Limiting** | ✅ Good | Comprehensive limits on all endpoints |
|
|
162
|
+
| **Input Validation** | ✅ Good | Schema validation, SQL injection protection |
|
|
163
|
+
| **TLS/HTTPS** | ✅ Good | DNS-01 wildcard certs, on-demand TLS protected |
|
|
164
|
+
| **Internal Secrets** | 🟡 Moderate | Protected but could be stronger (IP allowlist, mTLS) |
|
|
165
|
+
| **Audit Logging** | ✅ Good | Auth attempts, token operations logged |
|
|
166
|
+
| **Error Handling** | ✅ Good | Generic errors, no stack traces in production |
|
|
167
|
+
| **Infrastructure** | 🟡 Moderate | HTTP for internal comms, no request signing |
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 🎯 Recommended Next Steps
|
|
172
|
+
|
|
173
|
+
### ✅ Completed (Phase 2)
|
|
174
|
+
1. ✅ **Reduced `/internal/allow-tls` rate limit** to 60/min (from 120/min)
|
|
175
|
+
2. ✅ **Added request timeouts** (30s default, 5min for long ops)
|
|
176
|
+
3. ✅ **Redacted secrets in logs** (query params, headers automatically sanitized)
|
|
177
|
+
4. ✅ **Added IP allowlisting** for internal endpoints (configurable via `INTERNAL_IP_ALLOWLIST`)
|
|
178
|
+
5. ✅ **Enforced token max lifetime** (90 days default, configurable via `MAX_TOKEN_LIFETIME_DAYS`)
|
|
179
|
+
6. ✅ **Implemented request signing** middleware (optional, available for relay-to-backend)
|
|
180
|
+
7. ✅ **Added per-endpoint body size limits** (1MB/5MB/50MB presets)
|
|
181
|
+
|
|
182
|
+
### Short Term (Next Sprint)
|
|
183
|
+
1. **Enable request signing** for relay-to-backend communication (if relay supports custom headers)
|
|
184
|
+
2. **Add progressive rate limiting** (exponential backoff after repeated failures)
|
|
185
|
+
|
|
186
|
+
### Long Term (Future Phases)
|
|
187
|
+
3. **Migrate internal comms to HTTPS** (self-signed certs or mTLS)
|
|
188
|
+
4. **Add token rotation CLI command** (`uplink token rotate`)
|
|
189
|
+
5. **Add token expiry warnings** (notify users when tokens approach expiry)
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## 🔍 How to Verify Security
|
|
194
|
+
|
|
195
|
+
### Manual Checks
|
|
196
|
+
```bash
|
|
197
|
+
# 1. Verify internal secret is set
|
|
198
|
+
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
|
|
199
|
+
https://api.uplink.spot/v1/admin/system/status | jq '.hasInternalSecret'
|
|
200
|
+
|
|
201
|
+
# 2. Test rate limiting on /internal/allow-tls
|
|
202
|
+
for i in {1..130}; do
|
|
203
|
+
curl -s -o /dev/null -w "%{http_code}\n" \
|
|
204
|
+
"https://api.uplink.spot/internal/allow-tls?domain=test.x.uplink.spot"
|
|
205
|
+
done | sort | uniq -c
|
|
206
|
+
|
|
207
|
+
# 3. Verify security headers
|
|
208
|
+
curl -I https://api.uplink.spot/health | grep -i "x-content-type-options\|x-frame-options\|strict-transport-security"
|
|
209
|
+
|
|
210
|
+
# 4. Test token enumeration protection
|
|
211
|
+
# Should return 403 for invalid tokens, rate-limited after burst
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Automated Checks
|
|
215
|
+
```bash
|
|
216
|
+
# Run security audit script
|
|
217
|
+
API_BASE=https://api.uplink.spot node scripts/security-audit.mjs
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## 📝 Notes
|
|
223
|
+
|
|
224
|
+
- **Phase 1 Focus**: Internal secret protection and TLS hardening
|
|
225
|
+
- **Current Threat Model**: Assumes localhost is trusted (backend/relay on same host)
|
|
226
|
+
- **Future Considerations**: Multi-host deployments may require stronger internal auth (mTLS, request signing)
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
**Questions or concerns?** Review this document and prioritize based on your threat model and deployment architecture.
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Security Improvements - Phase 2
|
|
2
|
+
|
|
3
|
+
**Date:** January 2025
|
|
4
|
+
**Status:** ✅ Completed
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Phase 2 implements additional security hardening measures identified in the Phase 1 security assessment. These improvements address token enumeration, request timeouts, secret exposure in logs, IP allowlisting, request signing, token lifetime limits, and per-endpoint body size limits.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## ✅ Implemented Improvements
|
|
15
|
+
|
|
16
|
+
### 1. **Reduced Rate Limit for `/internal/allow-tls`**
|
|
17
|
+
- **Before**: 120 requests/minute per IP
|
|
18
|
+
- **After**: 60 requests/minute per IP
|
|
19
|
+
- **File**: `backend/src/middleware/rate-limit.ts`
|
|
20
|
+
- **Impact**: Reduces token enumeration attack surface by 50%
|
|
21
|
+
|
|
22
|
+
### 2. **Request Timeout Middleware**
|
|
23
|
+
- **Default**: 30 seconds for all requests
|
|
24
|
+
- **Long operations**: 5 minutes (for database provisioning, etc.)
|
|
25
|
+
- **File**: `backend/src/middleware/timeout.ts`
|
|
26
|
+
- **Impact**: Prevents slow-request DoS attacks
|
|
27
|
+
|
|
28
|
+
### 3. **Secret Redaction in Logs**
|
|
29
|
+
- **Automatic**: Secrets, tokens, passwords redacted from all logs
|
|
30
|
+
- **Scope**: Query params, headers, nested objects
|
|
31
|
+
- **File**: `backend/src/utils/logger.ts`
|
|
32
|
+
- **Impact**: Prevents secret exposure in log files, even if query params contain secrets
|
|
33
|
+
|
|
34
|
+
### 4. **IP Allowlisting for Internal Endpoints**
|
|
35
|
+
- **Default**: Localhost only (`127.0.0.1`, `::1`)
|
|
36
|
+
- **Configurable**: Via `INTERNAL_IP_ALLOWLIST` env var (comma-separated IPs or CIDR ranges)
|
|
37
|
+
- **File**: `backend/src/middleware/ip-allowlist.ts`
|
|
38
|
+
- **Usage**: `INTERNAL_IP_ALLOWLIST=127.0.0.1,10.0.0.0/8`
|
|
39
|
+
- **Impact**: Adds defense-in-depth for internal endpoints (even if secret leaks)
|
|
40
|
+
|
|
41
|
+
### 5. **Request Signing Middleware (Optional)**
|
|
42
|
+
- **Algorithm**: HMAC-SHA256 with timestamp
|
|
43
|
+
- **Replay protection**: Rejects requests older than 5 minutes
|
|
44
|
+
- **File**: `backend/src/middleware/request-signing.ts`
|
|
45
|
+
- **Status**: Implemented but not enforced (for Caddy compatibility)
|
|
46
|
+
- **Impact**: Available for relay-to-backend communication if needed
|
|
47
|
+
|
|
48
|
+
### 6. **Token Max Lifetime Enforcement**
|
|
49
|
+
- **Default**: 90 days (configurable via `MAX_TOKEN_LIFETIME_DAYS`)
|
|
50
|
+
- **Hard limit**: 365 days (never exceed 1 year)
|
|
51
|
+
- **File**: `backend/src/schemas/validation.ts`
|
|
52
|
+
- **Impact**: Prevents indefinitely-lived tokens, reduces risk of long-term compromise
|
|
53
|
+
|
|
54
|
+
### 7. **Per-Endpoint Body Size Limits**
|
|
55
|
+
- **Small**: 1MB (tunnel creation, token operations)
|
|
56
|
+
- **Medium**: 5MB (database operations)
|
|
57
|
+
- **Large**: 50MB (file uploads, bulk data)
|
|
58
|
+
- **File**: `backend/src/middleware/body-size.ts`
|
|
59
|
+
- **Usage**: Applied to tunnel creation route (1MB limit)
|
|
60
|
+
- **Impact**: Prevents memory exhaustion from oversized requests
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 📝 Configuration
|
|
65
|
+
|
|
66
|
+
### New Environment Variables
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# IP allowlist for internal endpoints (optional, defaults to localhost)
|
|
70
|
+
INTERNAL_IP_ALLOWLIST=127.0.0.1,10.0.0.0/8
|
|
71
|
+
|
|
72
|
+
# Max token lifetime in days (optional, defaults to 90)
|
|
73
|
+
MAX_TOKEN_LIFETIME_DAYS=90
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Existing Variables (Still Required)
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Required in production
|
|
80
|
+
RELAY_INTERNAL_SECRET=your-secret-here
|
|
81
|
+
CONTROL_PLANE_TOKEN_PEPPER=your-pepper-here
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 🔍 Testing
|
|
87
|
+
|
|
88
|
+
### Verify Rate Limiting
|
|
89
|
+
```bash
|
|
90
|
+
# Should return 429 after 60 requests in 1 minute
|
|
91
|
+
for i in {1..65}; do
|
|
92
|
+
curl -s -o /dev/null -w "%{http_code}\n" \
|
|
93
|
+
"https://api.uplink.spot/internal/allow-tls?domain=test.x.uplink.spot"
|
|
94
|
+
done | sort | uniq -c
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Verify IP Allowlisting
|
|
98
|
+
```bash
|
|
99
|
+
# From non-localhost IP, should return 403
|
|
100
|
+
curl -H "x-relay-internal-secret: $RELAY_INTERNAL_SECRET" \
|
|
101
|
+
https://api.uplink.spot/internal/allow-tls?domain=test.x.uplink.spot
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Verify Token Lifetime Enforcement
|
|
105
|
+
```bash
|
|
106
|
+
# Should fail with validation error if expiresInDays > 90
|
|
107
|
+
curl -X POST https://api.uplink.spot/v1/admin/tokens \
|
|
108
|
+
-H "Authorization: Bearer $ADMIN_TOKEN" \
|
|
109
|
+
-H "Content-Type: application/json" \
|
|
110
|
+
-d '{"role":"user","expiresInDays":365}'
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Verify Secret Redaction
|
|
114
|
+
```bash
|
|
115
|
+
# Check logs - secrets should appear as "[REDACTED]"
|
|
116
|
+
# Query params and headers with "secret", "token", "password" are automatically redacted
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## 📊 Security Posture Update
|
|
122
|
+
|
|
123
|
+
| Category | Before Phase 2 | After Phase 2 |
|
|
124
|
+
|----------|----------------|---------------|
|
|
125
|
+
| **Rate Limiting** | ✅ Good | ✅ Excellent (stricter limits) |
|
|
126
|
+
| **Request Timeouts** | ❌ None | ✅ Implemented |
|
|
127
|
+
| **Secret Exposure** | 🟡 Moderate (logs) | ✅ Protected (redacted) |
|
|
128
|
+
| **IP Allowlisting** | ❌ None | ✅ Implemented |
|
|
129
|
+
| **Request Signing** | ❌ None | ✅ Available (optional) |
|
|
130
|
+
| **Token Lifetime** | 🟡 Moderate (no limit) | ✅ Enforced (90 days) |
|
|
131
|
+
| **Body Size Limits** | 🟡 Moderate (global only) | ✅ Per-endpoint limits |
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 🚀 Deployment Notes
|
|
136
|
+
|
|
137
|
+
1. **Backward Compatible**: All changes are backward compatible
|
|
138
|
+
2. **Optional Features**: IP allowlisting and request signing are optional (fail-open if not configured)
|
|
139
|
+
3. **No Breaking Changes**: Existing tokens and configurations continue to work
|
|
140
|
+
4. **Environment Variables**: New env vars are optional (sensible defaults provided)
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## 📚 Files Changed
|
|
145
|
+
|
|
146
|
+
- `backend/src/middleware/rate-limit.ts` - Reduced rate limit
|
|
147
|
+
- `backend/src/middleware/timeout.ts` - New file
|
|
148
|
+
- `backend/src/middleware/ip-allowlist.ts` - New file
|
|
149
|
+
- `backend/src/middleware/request-signing.ts` - New file
|
|
150
|
+
- `backend/src/middleware/body-size.ts` - New file
|
|
151
|
+
- `backend/src/utils/logger.ts` - Added secret redaction
|
|
152
|
+
- `backend/src/server.ts` - Integrated new middlewares
|
|
153
|
+
- `backend/src/schemas/validation.ts` - Added token lifetime enforcement
|
|
154
|
+
- `backend/src/routes/tunnels.ts` - Applied body size limit
|
|
155
|
+
- `docs/SECURITY_ASSESSMENT.md` - Updated with Phase 2 status
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 🎯 Next Steps (Future Phases)
|
|
160
|
+
|
|
161
|
+
1. **Enable request signing** for relay-to-backend (if relay supports custom headers)
|
|
162
|
+
2. **Add progressive rate limiting** (exponential backoff)
|
|
163
|
+
3. **Migrate internal comms to HTTPS** (self-signed certs or mTLS)
|
|
164
|
+
4. **Add token rotation CLI command** (`uplink token rotate`)
|
|
165
|
+
5. **Add token expiry warnings** (notify users when tokens approach expiry)
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
**Questions?** See `docs/SECURITY_ASSESSMENT.md` for detailed security analysis.
|
package/package.json
CHANGED