Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed parsing of x-forwarded-* headers #12130

Merged
merged 13 commits into from
Oct 9, 2024
Merged

Conversation

thehansys
Copy link
Contributor

@thehansys thehansys commented Oct 5, 2024

Changes

This MR fixes parsing of x-forwarded-* headers such as x-forwarded-for, x-forwarded-host, x-forwarded-proto and x-forwarded-port. The current Astro version with node adapter cannot parse multiple values in these headers, for example x-forwarded-proto: https,http. This issue occurs when you run your Astro server behind two proxies, for example Cloudflare and then Nginx. All requests to SSR pages result in a 500 error in this case. Astro cannot be hosted with certain hosting providers because of this bug.

Testing

  • How to reproduce the bug with the current version: Just send request with following header "x-forwarded-proto: https,http" to any SSR page of Astro server with node adapter.
  • The change is covered by unit tests

Docs

  • This is bugfix. No change in documentation is needed.

Copy link

changeset-bot bot commented Oct 5, 2024

🦋 Changeset detected

Latest commit: af15d0c

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added the pkg: astro Related to the core `astro` package (scope) label Oct 5, 2024
@thehansys
Copy link
Contributor Author

@bluwy @ematipico Hey, can I ask you please for review? Is there anything else needed/missing in this MR to get this fix released? Thanks

Copy link
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

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

Awesome contribution @altano, thank you! I left some questions/suggestions

.changeset/slimy-buses-agree.md Outdated Show resolved Hide resolved
Comment on lines +88 to +89
const portInHostname = typeof hostname === 'string' && /:\d+$/.test(hostname);
const hostnamePort = portInHostname ? hostname : `${hostname}:${port}`
Copy link
Member

Choose a reason for hiding this comment

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

This isn't part of the PR description; why was this changed? What are we fixing?

Copy link
Contributor Author

@thehansys thehansys Oct 8, 2024

Choose a reason for hiding this comment

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

The old code was adding port to URL only when x-forwarded-port header was present and part of host header. This change handles edge-case when the port isn't part of the "host" header, the server listens on a non-standard port and there's no x-forward-port header in req. In that case it should fallback to req.socket.remotePort, default port for protocol in the following order and add it to URL (default ports such as 80 and 443 are hidden in the URL).

Althought, it's unlikely this would happen in a real-world scenario without broken proxy config / missing request headers.

Copy link
Member

Choose a reason for hiding this comment

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

Thank you for the thorough explanation!

packages/astro/src/core/app/node.ts Outdated Show resolved Hide resolved
packages/astro/src/core/app/node.ts Outdated Show resolved Hide resolved
@altano
Copy link
Contributor

altano commented Oct 8, 2024

Awesome contribution @altano, thank you! I left some questions/suggestions

Hah, as much as I would like your praise I don’t think you meant to tag me :(

@ematipico ematipico merged commit e96bcae into withastro:main Oct 9, 2024
13 checks passed
@astrobot-houston astrobot-houston mentioned this pull request Oct 9, 2024
@Fakerko
Copy link

Fakerko commented Oct 11, 2024

After updating to the latest version of Astro, it lists Astro.url.href, Astro.url.origin and Astro.url.host port in the address. So instead of https://www.example.com/ it prints the address with the port https://www.example.com:[RANDOM_PORT]/

Is this the correct behavior? I don't think the production should list the port after the URL, but maybe I'm wrong.

@ematipico
Copy link
Member

It's probably a regression. @Fakerko, can you open a bug report with a reproduction? @thehansys, would you be up to fixing the bug if it's valid?

@Fakerko
Copy link

Fakerko commented Oct 11, 2024

@ematipico done, bug report opened on #12192

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: astro Related to the core `astro` package (scope)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants