Skip to content

Commit 19d3945

Browse files
authored
685 improve passthrough (#687)
* Improve passthrough - bugfixes, security Signed-off-by: Mihai Criveti <[email protected]> * Improve passthrough - bugfixes, security Signed-off-by: Mihai Criveti <[email protected]> * Improve passthrough - bugfixes, security Signed-off-by: Mihai Criveti <[email protected]> --------- Signed-off-by: Mihai Criveti <[email protected]>
1 parent b6072ad commit 19d3945

File tree

10 files changed

+1204
-202
lines changed

10 files changed

+1204
-202
lines changed

.env.example

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,16 @@ MCPGATEWAY_ADMIN_API_ENABLED=true
119119
# Header Passthrough Configuration
120120
#####################################
121121

122-
# Default headers to pass through from client requests to backing MCP servers
123-
# Comma-separated list or JSON array format
124-
# Example: ["Authorization", "X-Tenant-Id", "X-Trace-Id"]
125-
DEFAULT_PASSTHROUGH_HEADERS=["Authorization", "X-Tenant-Id", "X-Trace-Id"]
122+
# SECURITY WARNING: Header passthrough is disabled by default for security.
123+
# Only enable if you understand the security implications and have reviewed
124+
# which headers should be passed through to backing MCP servers.
125+
# ENABLE_HEADER_PASSTHROUGH=false
126+
127+
# Default headers to pass through (when feature is enabled)
128+
# JSON array format recommended: ["X-Tenant-Id", "X-Trace-Id"]
129+
# Comma-separated also supported: X-Tenant-Id,X-Trace-Id
130+
# NOTE: Authorization header removed from defaults for security
131+
# DEFAULT_PASSTHROUGH_HEADERS=["X-Tenant-Id", "X-Trace-Id"]
126132

127133
#####################################
128134
# Security and CORS

docs/docs/overview/passthrough.md

Lines changed: 118 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# HTTP Header Passthrough
22

3+
⚠️ **Security Notice**: HTTP Header Passthrough is **disabled by default** for security reasons. Only enable this feature if you understand the security implications and have reviewed which headers should be passed through to backing MCP servers.
4+
35
The MCP Gateway supports **HTTP Header Passthrough**, allowing specific headers from incoming client requests to be forwarded to backing MCP servers. This feature is essential for maintaining authentication context and request tracing across the gateway infrastructure.
46

57
## Overview
@@ -8,66 +10,118 @@ When clients make requests through the MCP Gateway, certain headers (like authen
810

911
## Key Features
1012

13+
- **🔒 Security by Default**: Feature disabled by default - must be explicitly enabled
14+
- **🛡️ Header Validation**: Server-side and client-side header name and value validation
15+
- **🧹 Sanitization**: Automatic removal of dangerous characters and length limits
1116
- **Global Configuration**: Set default passthrough headers for all gateways
1217
- **Per-Gateway Override**: Customize header passthrough on a per-gateway basis
1318
- **Conflict Prevention**: Automatically prevents overriding existing authentication headers
1419
- **Admin UI Integration**: Configure passthrough headers through the web interface
1520
- **API Management**: Programmatic control via REST endpoints
21+
- **Rate Limiting**: Built-in rate limiting for configuration endpoints
1622

1723
## Configuration
1824

25+
### ⚠️ Enable the Feature (Required)
26+
27+
**The header passthrough feature is disabled by default for security.** You must explicitly enable it:
28+
29+
```bash
30+
# Enable the feature (disabled by default)
31+
ENABLE_HEADER_PASSTHROUGH=true
32+
33+
# Or in .env file
34+
ENABLE_HEADER_PASSTHROUGH=true
35+
```
36+
37+
**Warning**: Only enable this feature if you:
38+
- Understand the security implications
39+
- Have reviewed which headers should be passed through
40+
- Trust the backing MCP servers with the forwarded headers
41+
- Have implemented proper network security
42+
1943
### Environment Variables
2044

2145
Set global default headers using the `DEFAULT_PASSTHROUGH_HEADERS` environment variable:
2246

2347
```bash
24-
# JSON array format
25-
DEFAULT_PASSTHROUGH_HEADERS=["Authorization", "X-Tenant-Id", "X-Trace-Id"]
48+
# JSON array format (recommended)
49+
DEFAULT_PASSTHROUGH_HEADERS=["X-Tenant-Id", "X-Trace-Id"]
50+
51+
# Comma-separated format (also supported)
52+
DEFAULT_PASSTHROUGH_HEADERS=X-Tenant-Id,X-Trace-Id
2653

2754
# Or in .env file
28-
DEFAULT_PASSTHROUGH_HEADERS=["Authorization", "X-Tenant-Id", "X-Trace-Id"]
55+
DEFAULT_PASSTHROUGH_HEADERS=["X-Tenant-Id", "X-Trace-Id"]
2956
```
3057

58+
**Security Notes**:
59+
- `Authorization` header is **not included in defaults** for security
60+
- Only add `Authorization` if you fully understand the token leakage risks
61+
- Header names are validated against pattern: `^[A-Za-z0-9-]+$`
62+
- Header values are sanitized (newlines removed, length limited to 4KB)
63+
3164
### Admin UI Configuration
3265

66+
**Prerequisites**:
67+
1. Set `ENABLE_HEADER_PASSTHROUGH=true` in your environment
68+
2. Restart the MCP Gateway service
69+
3370
#### Global Configuration
3471
Access the admin interface to set global passthrough headers that apply to all gateways by default.
3572

73+
🛡️ **Client-side validation** automatically checks:
74+
- Header names match pattern `^[A-Za-z0-9-]+$`
75+
- Header values don't contain newlines or excessive length
76+
- Invalid headers are rejected with clear error messages
77+
3678
#### Per-Gateway Configuration
3779
When creating or editing gateways:
3880

3981
1. Navigate to the **Gateways** section in the admin UI
4082
2. Click **Add Gateway** or edit an existing gateway
4183
3. In the **Passthrough Headers** field, enter a comma-separated list:
4284
```
43-
Authorization, X-Tenant-Id, X-Trace-Id
85+
X-Tenant-Id, X-Trace-Id, X-Request-Id
4486
```
87+
**⚠️ Avoid including `Authorization` unless absolutely necessary**
4588
4. Gateway-specific headers override global defaults
89+
5. The UI validates headers in real-time and shows security warnings
4690

4791
### API Configuration
4892

93+
**Rate Limited**: Configuration endpoints are rate-limited (20-30 requests/minute) for security.
94+
4995
#### Get Global Configuration
5096
```bash
5197
GET /admin/config/passthrough-headers
98+
Authorization: Bearer <your-jwt-token>
5299
```
53100

54101
Response:
55102
```json
56103
{
57-
"passthrough_headers": ["Authorization", "X-Tenant-Id", "X-Trace-Id"]
104+
"passthrough_headers": ["X-Tenant-Id", "X-Trace-Id"]
58105
}
59106
```
60107

61108
#### Update Global Configuration
62109
```bash
63110
PUT /admin/config/passthrough-headers
64111
Content-Type: application/json
112+
Authorization: Bearer <your-jwt-token>
65113

66114
{
67-
"passthrough_headers": ["Authorization", "X-Custom-Header"]
115+
"passthrough_headers": ["X-Tenant-Id", "X-Custom-Header"]
68116
}
69117
```
70118

119+
**Security Validation**: The API automatically:
120+
- Validates header names against `^[A-Za-z0-9-]+$` pattern
121+
- Rejects invalid characters and formats
122+
- Sanitizes header values when used
123+
- Logs all configuration changes for audit
124+
71125
## How It Works
72126

73127
### Header Processing Flow
@@ -101,23 +155,46 @@ graph LR
101155

102156
## Security Considerations
103157

158+
### 🛡️ Security-by-Default Features
159+
160+
**Feature Flag Protection**:
161+
- Header passthrough is **disabled by default** (`ENABLE_HEADER_PASSTHROUGH=false`)
162+
- Must be explicitly enabled with full awareness of security implications
163+
- Can be disabled instantly by setting the flag to `false`
164+
165+
**Header Sanitization**:
166+
- **Injection Prevention**: Removes newlines (`\r\n`) that could enable header injection attacks
167+
- **Length Limiting**: Restricts header values to 4KB maximum to prevent DoS
168+
- **Control Character Filtering**: Removes dangerous control characters (except tab)
169+
- **Validation**: Header names must match `^[A-Za-z0-9-]+$` pattern
170+
171+
**Rate Limiting**:
172+
- Configuration endpoints limited to 20-30 requests/minute
173+
- Prevents automated attacks on configuration
174+
- Configurable via existing rate limiting settings
175+
104176
### Conflict Prevention
105177

106178
The system automatically prevents header conflicts:
107179

108180
- **Basic Auth**: Skips `Authorization` header if gateway uses basic authentication
109181
- **Bearer Auth**: Skips `Authorization` header if gateway uses bearer token authentication
182+
- **Existing Headers**: Won't override pre-existing headers in base request
110183
- **Warnings**: Logs warnings when headers are skipped due to conflicts
111184

112185
### Header Validation
113186

114-
- Headers are validated before forwarding
115-
- Empty or invalid headers are filtered out
116-
- Only explicitly configured headers are passed through
187+
- **Server-side validation**: Headers validated against security patterns
188+
- **Client-side validation**: Admin UI provides real-time validation feedback
189+
- **Case-insensitive matching**: Handles header case variations safely
190+
- **Empty filtering**: Empty or invalid headers are filtered out
191+
- **Explicit configuration**: Only explicitly configured headers are passed through
117192

118193
## Use Cases
119194

120195
### Authentication Context
196+
⚠️ **Security Warning**: Be extremely careful when forwarding authentication tokens.
197+
121198
Forward authentication tokens to maintain user context:
122199
```bash
123200
# Client request includes
@@ -150,14 +227,14 @@ X-Organization: acme_corp
150227

151228
### Basic Setup
152229
```bash
153-
# .env file
154-
DEFAULT_PASSTHROUGH_HEADERS=["Authorization"]
230+
# .env file (Authorization not recommended in defaults)
231+
DEFAULT_PASSTHROUGH_HEADERS=["X-Tenant-Id"]
155232
```
156233

157234
### Multi-Header Configuration
158235
```bash
159-
# .env file with multiple headers
160-
DEFAULT_PASSTHROUGH_HEADERS=["Authorization", "X-Tenant-Id", "X-Trace-Id", "X-Request-Id"]
236+
# .env file with multiple headers (safer defaults)
237+
DEFAULT_PASSTHROUGH_HEADERS=["X-Tenant-Id", "X-Trace-Id", "X-Request-Id"]
161238
```
162239

163240
### Gateway-Specific Override
@@ -175,9 +252,17 @@ DEFAULT_PASSTHROUGH_HEADERS=["Authorization", "X-Tenant-Id", "X-Trace-Id", "X-Re
175252
### Common Issues
176253

177254
#### Headers Not Being Forwarded
178-
- Verify header names in configuration match exactly (case-sensitive)
255+
256+
**Most Common Cause - Feature Disabled**:
257+
-**Check**: Is `ENABLE_HEADER_PASSTHROUGH=true` set in your environment?
258+
-**Check**: Did you restart the gateway after setting the flag?
259+
-**Check**: Are you seeing "Header passthrough is disabled" in debug logs?
260+
261+
**Other Causes**:
262+
- Verify header names in configuration match exactly (case-insensitive matching)
179263
- Check for authentication conflicts in logs
180264
- Ensure gateway configuration overrides aren't blocking headers
265+
- Verify header names pass validation (only letters, numbers, hyphens allowed)
181266

182267
#### Authentication Conflicts
183268
If you see warnings like:
@@ -194,6 +279,19 @@ Skipping passthrough header 'Authorization' - conflicts with existing basic auth
194279
- Restart the gateway after environment variable changes
195280
- Verify database migration has been applied
196281
- Check admin API responses to confirm configuration is saved
282+
- Verify rate limiting isn't blocking your configuration requests (20-30/min limit)
283+
284+
#### Header Validation Errors
285+
If you see validation errors in the Admin UI or API:
286+
287+
**Header Name Validation**:
288+
- Only letters, numbers, and hyphens allowed: `A-Za-z0-9-`
289+
- Examples: ✅ `X-Tenant-Id`, `Authorization``X_Tenant_ID`, `My Header`
290+
291+
**Header Value Issues**:
292+
- No newlines (`\r` or `\n`) allowed in values
293+
- Maximum length: 4KB per header value
294+
- Control characters are automatically removed
197295

198296
### Debug Logging
199297

@@ -203,9 +301,12 @@ LOG_LEVEL=DEBUG
203301
```
204302

205303
Look for log entries containing:
206-
- `Passthrough headers configured`
207-
- `Skipping passthrough header`
208-
- `Adding passthrough header`
304+
- `Header passthrough is disabled` - Feature flag is off
305+
- `Passthrough headers configured` - Headers are being processed
306+
- `Skipping passthrough header` - Header blocked due to conflict
307+
- `Adding passthrough header` - Header successfully forwarded
308+
- `Invalid header name` - Header name validation failed
309+
- `Header value became empty after sanitization` - Header value was sanitized away
209310

210311
## API Reference
211312

0 commit comments

Comments
 (0)