Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ If you'd like to use [profiler.firefox.com](https://profiler.firefox.com) via UR
FX_PROFILER_HOST="0.0.0.0" yarn start
```

You'll probably also want to add your non-localhost domains to the `allowedHosts` property in `server.js`.
When using `FX_PROFILER_HOST="0.0.0.0"`, any hostname is allowed so you can access the profiler from other devices on your network. If you want to expose only a specific hostname instead, set `FX_PROFILER_HOST` to that hostname directly and it will be added to the allowed hosts automatically.

## Finding something to work on

Expand Down
19 changes: 13 additions & 6 deletions scripts/lib/dev-server.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,20 @@ const EXTRA_HEADERS = {
// Allowed hosts for dev server
const ALLOWED_HOSTS = ['localhost', '.app.github.dev'];

function isHostAllowed(hostHeader) {
function isHostAllowed(hostHeader, boundHost) {
if (!hostHeader) {
return false;
}

// Extract hostname without port
// When binding to all interfaces, allow any host.
if (boundHost === '0.0.0.0' || boundHost === '::' || boundHost === '::0') {
return true;
}

const hostname = hostHeader.split(':')[0];
const allowedHosts = [...ALLOWED_HOSTS, boundHost];

// Check exact match or suffix match for wildcard patterns
return ALLOWED_HOSTS.some((allowedHost) => {
return allowedHosts.some((allowedHost) => {
if (allowedHost.startsWith('.')) {
// Wildcard pattern like '.app.github.dev'
return hostname.endsWith(allowedHost);
Expand Down Expand Up @@ -75,7 +79,7 @@ export async function startDevServer(buildConfig, options = {}) {
// Create HTTP server
const server = http.createServer((req, res) => {
// Validate Host header
if (!isHostAllowed(req.headers.host)) {
if (!isHostAllowed(req.headers.host, host)) {
res.writeHead(403, { 'Content-Type': 'text/plain' });
res.end('Invalid Host header');
return;
Expand All @@ -86,7 +90,10 @@ export async function startDevServer(buildConfig, options = {}) {
port: esbuildServerPort,
path: req.url,
method: req.method,
headers: req.headers,
headers: {
...req.headers,
host: hostname + ':' + esbuildServerPort,
},
};

// Forward each incoming request to esbuild
Expand Down