Skip to content

fix: use request.headers.host (with port) in buildResourceUrl#251

Merged
melvincarvalho merged 1 commit into
gh-pagesfrom
issue-250-fix-port-in-resourceurl
Apr 3, 2026
Merged

fix: use request.headers.host (with port) in buildResourceUrl#251
melvincarvalho merged 1 commit into
gh-pagesfrom
issue-250-fix-port-in-resourceurl

Conversation

@melvincarvalho

Copy link
Copy Markdown
Contributor

Summary

buildResourceUrl used request.hostname which strips the port. ACL matching failed on non-standard ports because the constructed URL http://localhost/path never matched the ACL's http://localhost:4443/path.

Fix: use request.headers.host which includes the port.

Tested

Full 402 flow verified:

  1. Create resource + PaymentCondition ACL → 402
  2. Deposit testnet4 sats → balance credited
  3. Retry → 200 OK + content

353 tests pass.

Fixes #250

Fastify's request.hostname strips the port, so ACL matching fails on
non-standard ports. The constructed URL http://localhost/path never
matches the ACL's http://localhost:4443/path.

Use request.headers.host which includes the port.

Fixes #250
@melvincarvalho
melvincarvalho requested a review from Copilot April 3, 2026 01:01
@melvincarvalho
melvincarvalho merged commit 33e6cdd into gh-pages Apr 3, 2026
2 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes ACL matching on non-standard ports by ensuring URLs constructed for WAC checks include the request port (e.g., localhost:4443 instead of localhost).

Changes:

  • Update buildResourceUrl to prefer request.headers.host (includes port) over request.hostname (strips port).
  • Update the HTML error page’s baseUrl construction to use host-with-port as well.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/auth/middleware.js
Comment on lines +27 to 30
// Use request.headers.host (includes port) instead of request.hostname (strips port)
const host = request.headers.host || request.hostname;
if (request.subdomainsEnabled && request.baseDomain &&
request.hostname === request.baseDomain && !request.podName) {

Copilot AI Apr 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

buildResourceUrl is used for WAC authorization decisions, but this change switches to request.headers.host directly. The Host header (and with trustProxy: true, proxy-provided host headers) is client-influenced and can be spoofed, which risks incorrect ACL matching across virtual hosts. Consider deriving the authority from Fastify’s trusted properties and only appending a validated port (or validating that headers.host matches request.hostname), and include x-forwarded-host when running behind a proxy (consistent with src/ap/index.js:70-78).

Copilot uses AI. Check for mistakes.
Comment thread src/auth/middleware.js
Comment on lines 29 to 36
@@ -33,7 +35,7 @@ function buildResourceUrl(request, urlPath) {
return `${request.protocol}://${podName}.${request.baseDomain}${remainder}`;
}

Copilot AI Apr 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the subdomain-normalization branch, the returned URL omits any non-standard port even after introducing host with port. If the server runs subdomain mode on a non-default port, ACL URLs that include the port will still not match. Consider preserving the port when building ${podName}.${baseDomain} (e.g., by extracting the port from the incoming authority and appending it).

Copilot uses AI. Check for mistakes.
Comment thread src/auth/middleware.js
Comment on lines +185 to 186
const baseUrl = `${request.protocol}://${request.headers.host || request.hostname}`;

Copilot AI Apr 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

baseUrl is built using request.headers.host and then interpolated into HTML attributes (e.g., href="${baseUrl}/"). Because Host is user-controlled, this can enable reflected HTML injection/XSS if the header contains characters like quotes. Prefer a sanitized/validated authority (or escape before injecting into HTML) rather than using the raw header value.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: buildResourceUrl strips port — ACL matching fails on non-standard ports

2 participants