🌐 CORS Proxy Module
📖 Overview
The CORS Proxy module provides a simple HTTP proxy server that bypasses Cross-Origin Resource Sharing (CORS) restrictions. Frontend applications can route external API requests through this proxy to avoid browser CORS limitations.
File Path: internal/api/v1/cors-proxy/
Key Features
- CORS Bypass: Proxies requests to any external URL
- Method Support: Handles GET, POST, PUT, PATCH, DELETE
- Stream Response: Pipes responses directly to client
- Header Preservation: Forwards response headers
- OPTIONS Preflight: Handles CORS preflight requests
� Directory Structure
cors-proxy/
└── 📄 index.js - Complete proxy implementation (single file)
Note: This is a minimal module with all logic in one file - no controllers/services separation needed.
�🔧 How It Works
Request Flow
sequenceDiagram
participant Frontend
participant CORSProxy as CORS Proxy
participant ExternalAPI as External API
Frontend->>CORSProxy: Request with Target-URL header
CORSProxy->>CORSProxy: Set CORS headers (allow *)
CORSProxy->>ExternalAPI: Forward request to Target-URL
ExternalAPI-->>CORSProxy: Response (any origin)
CORSProxy->>CORSProxy: Copy response headers
CORSProxy-->>Frontend: Stream response
Usage Example
Frontend Code:
// Instead of directly calling external API (blocked by CORS):
// fetch('https://external-api.com/data')
// Route through CORS proxy:
fetch('/api/v1/cors-proxy/', {
method: 'GET',
headers: {
'Target-URL': 'https://external-api.com/data',
},
});
Implementation
File: index.js (42 lines)
router.all('*', function (req, res, next) {
// 1. Set permissive CORS headers
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, PUT, PATCH, POST, DELETE');
res.header('Access-Control-Allow-Headers', req.header('access-control-request-headers'));
// 2. Handle OPTIONS preflight
if (req.method === 'OPTIONS') {
return res.send();
}
// 3. Get target URL from header
var targetURL = req.header('Target-URL');
if (!targetURL) {
return res.status(500).json({ error: 'Missing Target-URL header' });
}
// 4. Proxy request to target
axios({
url: targetURL + (req.url === '/' ? '' : req.url),
method: req.method,
responseType: 'stream',
data: req.method !== 'GET' ? req.body : null,
})
.then(resp => {
// 5. Forward response headers
Object.entries(resp.headers).forEach(([name, value]) => {
res.header(name, value);
});
// 6. Stream response body
resp.data.pipe(res);
})
.catch(err => logger.error({ initiator: 'cors-proxy', error: err }));
});
⚙️ Configuration
CORS Headers
- Allow-Origin:
*(all origins) - Allow-Methods: GET, PUT, PATCH, POST, DELETE
- Allow-Headers: Mirrors client's request headers
Request Requirements
- Target-URL header (required): Full URL to proxy
- Method: Any HTTP method
- Body: Forwarded for non-GET requests
- Path: Appended to Target-URL
⚠️ Important Notes
- 🔓 Open Proxy: No authentication or URL validation
- ⚠️ Security Risk: Can be used to access any external API
- 🎯 Production Hardening: Should restrict allowed target domains
- 📦 Streaming: Responses are streamed (supports large files)
- 🌍 Public Access: Typically requires authentication in production
- 🚫 Rate Limiting: No built-in rate limiting
🛡️ Security Considerations
Recommended Improvements
// Add whitelist of allowed domains
const ALLOWED_DOMAINS = ['https://api.example.com', 'https://data.partner.com'];
const targetURL = req.header('Target-URL');
const isAllowed = ALLOWED_DOMAINS.some(domain => targetURL.startsWith(domain));
if (!isAllowed) {
return res.status(403).json({ error: 'Target domain not allowed' });
}
Potential Abuse Scenarios
- SSRF Attack: Accessing internal network resources
- Rate Limit Bypass: Circumventing external API rate limits
- Content Scraping: Harvesting protected content
- Traffic Amplification: Using proxy for DDoS attacks
Last Updated: 2025-01-08
Module Path:internal/api/v1/cors-proxy/
Main Route:ALL /api/v1/cors-proxy/*
Required Header:Target-URL