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

fix: handle request paths starting with // #6

Merged
merged 1 commit into from
Jan 17, 2024
Merged

Conversation

bajtos
Copy link
Member

@bajtos bajtos commented Jan 17, 2024

Calling new URL('//foo', 'http://127.0.0.1') produces href http://foo/. As a result, we were treating all requests for paths starting with double slash as if no path was specified.

Links:

Calling `new URL('//foo', 'http://127.0.0.1')` produces href
`http://foo/`. As a result, we were treating all requests for
paths starting with double slash as if no path was specified.

Signed-off-by: Miroslav Bajtoš <[email protected]>
@bajtos bajtos merged commit 11fc6b1 into main Jan 17, 2024
5 checks passed
@bajtos bajtos deleted the fix-double-slash-in-path branch January 17, 2024 07:56
@@ -32,7 +32,9 @@ export const createHandler = ({
* @param {import('pg').Pool} pgPool
*/
const handler = async (req, res, pgPool) => {
const { pathname, searchParams } = new URL(req.url, 'http://127.0.0.1')
// Fix the edge case: new URL('//foo', 'http://127.0.0.1') produces href "http://foo/"
const reqUrl = req.url.replace(/^\/+/, '/')
Copy link
Member

Choose a reason for hiding this comment

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

I disagree with this change. The url ${HOST}// is invalid and doesn't need to be supported.

Copy link
Member Author

Choose a reason for hiding this comment

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

According to https://stackoverflow.com/a/20524044/69868, which links to several other resources including RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax, a path starting with a double slash is a valid one.

Consensus: browsers will do the request as-is, they will not alter the request. The / character is the path separator, but as path segments are defined as:

path-abempty  = *( "/" segment )
segment       = *pchar

Means the slash after http://example.com/ can directly be followed by another slash, ad infinitum. Servers might ignore it, but browsers don't, as you have figured out.

TBH, I would rather start using a framework like Fastify that would handle these low-level details for us.

Copy link
Member

Choose a reason for hiding this comment

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

The source says that URLs like this can be valid, but that the server can handle it as it wish. We can be strict and just disallow it. If we want to keep allowing it then I agree that a framework would be great, as what we have now with this PR feels a bit like a hack.

I propose to revert this PR and keep the server simple and strict. Or do you have a use-case for supporting double slashes?

Copy link
Member Author

Choose a reason for hiding this comment

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

Well, I was surprised to learn that a request starting with double slashes was treated the same way as a request starting with /. That's a bug I want to fix, to avoid further surprises.

An alternative solution to this PR is to return 404 when request.url starts with //. Is such a solution in line with your proposal to be strict and just disallow it?

if (req.url.startsWith('//')) {
  return notFound(res)
}

To be clear, I am happy to change this, but I want to find a solution that behaves as one would expect.

Another option that comes to my mind, I would need to double-check that it works as I think it should work.

- new URL(req.url, 'http://127.0.0.1')
+ new URL(`http://127.0.0.1${req.url}`)

Copy link
Member

Choose a reason for hiding this comment

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

An alternative solution to this PR is to return 404 when request.url starts with //. Is such a solution in line with your proposal to be strict and just disallow it?

I would like not to mention // at all. It's a pity that the URL constructor allows the relative first argument to go "above" the provided base URL. Maybe yeah new URL(http://127.0.0.1${req.url}`)` is a simple improvement 👍

Copy link
Member Author

Choose a reason for hiding this comment

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

FWIW, http://api.filspark.com//rounds/current handles double-slash as a single slash. I want our services to behave consistently.

I am going to use http://127.0.0.1${req.url} approach.

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.

2 participants