refactor(server): share one proxy-header check across the local gates

localRequestGate.mjs owns the reverse-proxy header list and hasProxySignals;
Provider Settings, the cross-site gate and /mcp all use it instead of two
copies of the same nine names. The changelog credits the cross-site gate.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Sameh KhamisandClaude Opus 5.5 committed 2026-10-02 20:02:48 -07:00
1 parent bbf4976f5e
commit 6cdd6c8af9
5 files changed
+34 -34

No files matched your search

+14 -7
View File
@@ -21,10 +21,9 @@
*/
/**
* Reverse-proxy / CDN forwarding headers. Their presence means the request did
* not originate on this machine, whatever its socket says. Kept as this
* module's own list (keySetupCore.mjs carries the same nine names for the
* credential panel) so the gate has no imports and can sit in any package
* boundary.
* not originate on this machine, whatever its socket says. This module owns
* the list for every local gate (the credential panel and /mcp import
* `hasProxySignals`), and has no imports so it can sit in any package boundary.
*/
export const PROXY_SIGNALS = Object.freeze([
'forwarded',
@@ -38,6 +37,16 @@ export const PROXY_SIGNALS = Object.freeze([
'cf-ray',
]);
/**
* Whether a request carries reverse-proxy or CDN forwarding headers. `headers`
* is keyed by lower-case header name.
*/
export function hasProxySignals(headers = {}) {
return PROXY_SIGNALS.some(
(name) => String(headers[name] || '').trim() !== '',
);
}
/**
* Compute a request's own authority (an origin string) from its protocol and
* Host header. Unlike the credential-panel gate's localhost-restricted
@@ -90,9 +99,7 @@ export function admitSameSiteRequest({
} = {}) {
// (1) A request carrying reverse-proxy / CDN forwarding headers did not
// originate on this machine, whatever its socket says.
if (
PROXY_SIGNALS.some((name) => String(proxyHeaders[name] || '').trim() !== '')
) {
if (hasProxySignals(proxyHeaders)) {
return {
ok: false,
status: 403,