Deploy your own version of this example with a couple of clicks
A security-hardened, multi-host, reverse proxy server built with Deno.
This project provides a simple yet powerful proxy that forwards incoming requests to different target hosts based on the URL path. It's designed to be deployed as a standalone service, for example on Deno Deploy.
It's an ideal solution for:
- Bypassing CORS restrictions during development.
- Consolidating multiple API endpoints under a single domain.
- Adding a layer of security (rate limiting, header sanitization) in front of existing services.
- Dynamic Host Proxying: Routes requests like
https://my-proxy.dev/api.example.com/datatohttps://api.example.com/data. - Security First: Built with a security-focused mindset to be safely exposed to the internet.
- Whitelist Enforcement: Only allows proxying to hosts specified in an
ALLOWED_HOSTSlist. - Wildcard Support: Allows flexible whitelisting of subdomains (e.g.,
*.github.com). - Path Traversal Prevention: Safely handles hostnames to prevent bypass attacks.
- Rate Limiting: Protects against DoS attacks and abuse by limiting requests per IP.
- Request Timeouts: Prevents slowloris-style attacks and resource exhaustion.
- Header Sanitization: Strips sensitive headers from both incoming and outgoing traffic.
- Structured Logging: Outputs logs in JSON format for easy parsing and monitoring.
- Configurable: All security parameters are configurable via environment variables.
The proxy extracts the target hostname from the first segment of the URL path.
Example Request:
https://your-proxy-domain.deno.dev/mcp.exa.ai/some/path?query=1
- The proxy receives the request.
- It extracts
mcp.exa.aias the target host. - It validates that
mcp.exa.aiis a valid hostname and is present in theALLOWED_HOSTSwhitelist. - It reconstructs the target URL:
https://mcp.exa.ai/some/path?query=1. - It forwards the original request (including method, body, and sanitized headers) to the target URL.
- The response from the target is then streamed back to the original client.
- Deno (v1.x or later)
-
Clone the repository:
git clone https://github.com/franchb/deno-proxy.git cd deno-proxy -
Set Environment Variables: The
ALLOWED_HOSTSvariable is required. This is a comma-separated list of host patterns that the proxy is allowed to connect to.On macOS/Linux:
export ALLOWED_HOSTS="api.github.com,*.deno.land"
On Windows (Command Prompt):
set ALLOWED_HOSTS=api.github.com,*.deno.land
-
Run the server: The server requires network and environment variable permissions.
deno run --allow-net --allow-env=ALLOWED_HOSTS,PROXY_TIMEOUT_MS,RATE_LIMIT_MAX_REQUESTS,RATE_LIMIT_WINDOW_MS proxy.ts
The server will start on
http://localhost:8000. -
Test the proxy:
# This will be proxied to https://api.github.com/users/denoland curl http://localhost:8000/api.github.com/users/denoland # This will be blocked with a 403 Forbidden error curl http://localhost:8000/google.com
All configuration is handled through environment variables, making it easy to deploy and manage.
| Variable | Description | Default | Required |
|---|---|---|---|
ALLOWED_HOSTS |
Comma-separated list of whitelisted host patterns. Wildcards (*) are supported for a single hostname segment. |
"" |
Yes |
PROXY_TIMEOUT_MS |
Timeout in milliseconds for requests to the target host. | 15000 |
No |
RATE_LIMIT_WINDOW_MS |
The time window for rate limiting, in milliseconds. | 60000 |
No |
RATE_LIMIT_MAX_REQUESTS |
Maximum number of requests allowed from a single IP within the window. | 100 |
No |
This project is perfectly suited for Deno Deploy.
-
Fork this repository.
-
Create a new project on Deno Deploy and link it to your forked repository.
-
Choose the
proxy.tsfile as the entry point. -
In the project settings on Deno Deploy, go to Settings -> Environment Variables and add your configuration. At a minimum, you must set
ALLOWED_HOSTS.
This proxy has been built with several security measures in place.
- Whitelist is Paramount: The
ALLOWED_HOSTSlist is your primary defense. Keep it as restrictive as possible. Avoid overly permissive patterns like*or*.com. - Rate Limiting: The default rate limits are sensible but should be tuned based on your expected traffic. Note that the in-memory rate limiter will reset with each deployment. For a more persistent solution, an external service (like a Redis-based limiter) would be needed.
- Logging: The proxy outputs structured JSON logs for security events (forbidden attempts, timeouts, errors). In a production environment, you should forward these logs to a dedicated logging service for monitoring and alerting.
This project is licensed under the MIT License. See the LICENSE file for details.
