express icon indicating copy to clipboard operation
express copied to clipboard

[feature request] disable decode_param for path routing

Open lublak opened this issue 2 years ago • 7 comments

I have some special urls thats get mapped to local files like image50%.png.

app.get('/open/:path(*)', (req, res) => {})

But it doesn't work because express automaticly calls decode_param. It throws Failed to decode param.

lublak avatar Feb 16 '22 16:02 lublak

Hi @lublak sorry you are having trouble. There is no need to disable the decoding for this. Your client should be sending the URL as a valid encoding of /open/image50%25.png 👍 . If you really want to avoid decoding for your use-case if you need to accept improperly encoded URLs, you can use something like app.use('/open', (req, res) => {}) and then req.url will just be the part after /open. I hope that helps!

dougwilson avatar Feb 16 '22 16:02 dougwilson

Apologies, I didn't mean to close the issue, as we could add some kind of app-level config to disabled/custom the param decoding.

dougwilson avatar Feb 16 '22 16:02 dougwilson

@dougwilson The problem is that the client is Firefox and it sends this over quite validly (not with %25) the user of course enters image50%.png and not image50%25.png. I will try that with app.use('/open', (req, res) => {}) tomorrow.

lublak avatar Feb 16 '22 17:02 lublak

Hi @lublak by invalid, I am referring to what Express.js considers invalid. The reason you are getting the error is indeed because the URL is invalid according to Express.js, as it expects parameters to be URL-encoded and if the JavaScript function to decode URL-encoded strings, decodeURIComplement throws as invalid, then Express.js will bubble up that error. I did not make any statements regarding how Firefox works, of course, though my understanding is it will send whatever the user types in, regardless of what the web server is expecting. My guess, though, is that Firefox will still turn spaces into %20, so if you disable the param decoding, a URL like /open/foo bar.jpg will end up as foo%20bar.jpg on the server when you have decoding disabled, even if the user typed in a literal space, so turning it off probably has down sides.

dougwilson avatar Feb 16 '22 17:02 dougwilson

@dougwilson That's right I didn't think about that of course blank characters are then given as %20 by the browser. The same is true for other characters like "ä". For me it means that all "invalid" % characters must be replaced by %25 to decodeURIComplement .

app.use('/open', (req, res) => {
   const path = decodeURIComplement(makeItValid(req.url));
})

I will try to implement it tomorrow. Thanks for the thought :)

lublak avatar Feb 16 '22 18:02 lublak

No problem. The current behavior of decoding params won't be changed, as there can be security implications of your proposal, but it would depend on the application if they are relevant or not. But the feature request, as I see it, would allow the user (like yourself) to implement any kind of decoding routine as they see fit, which would allow you to write any type of logic that works for your particular use case 👍

dougwilson avatar Feb 16 '22 18:02 dougwilson

@dougwilson for me it works fine :) thanks for your tip. But i decided only support some %. urlPath.replace(/%([&$%.-_ #?=*/]|$)/g, '%25$1')

lublak avatar Feb 17 '22 10:02 lublak