Skip to content

Conversation

MegaManSec
Copy link

Ensures all unsafe characters in the request URL are percent-encoded before including the path in the error response, mitigating XSS risks.

Visiting the proxied page https://host.com/?<script>alert(document.cookie);</script> when an error occured, would result in the js being executed.

Motivation and Context

We don't want to render arbitrary HTML and execute arbitrary just because it's in the path.

How has this been tested?

manually

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

@chimurai
Copy link
Owner

Response is already escaped:

image

Do you have a reproduction of a XSS?

@MegaManSec
Copy link
Author

MegaManSec commented Aug 17, 2025

Remove the ? From your url

Chrome sends the url with escaped path variables

@chimurai
Copy link
Owner

chimurai commented Aug 17, 2025

Same result in Chrome and Safari (without ?):

image

@chimurai
Copy link
Owner

chimurai commented Aug 17, 2025

Can you provide a reproducible example about your claim of js being executed?

Visiting the proxied page https://host.com/?<script>alert(document.cookie);</script> when an error occured, would result in the js being executed

@MegaManSec
Copy link
Author

Sure, will send something tomorrow. If you use curl you can see it isn't escaped by the server side

@chimurai
Copy link
Owner

When I log the req.url variable it's already escaped:

const host = req.headers && req.headers.host;
res.end(`Error occurred while trying to proxy: ${host}${req.url}`);

req.url: /?%3Cscript%3Ealert(document.cookie);%3C/script%3E

Happy to see I reproduction of the issue 👍

@MegaManSec
Copy link
Author

Right, apologies; I only actually tested this with curl originally and misunderstood the encoding that browsers all do these days. So the browser is actually sending the escaped values, and that's being echoed verbatim. For example:

$ curl "http://localhost:3000/api/<><><><><"
Error occurred while trying to proxy: localhost:3000/<><><><><

Given this, not sure if you want to include this "fix". Up to you!

@chimurai
Copy link
Owner

I tried a local request with curl and the special characters are already escaped.

Can you provide a working reproduction so it can be investigated?

@MegaManSec
Copy link
Author

[jrogers@Joshuas-Macbook-Pro14:/tmp]$ mkdir i/
[jrogers@Joshuas-Macbook-Pro14:/tmp]$ cd i
[jrogers@Joshuas-Macbook-Pro14:/tmp/i]$ cat <<EOF >app.js
> import express from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware';

const app = express();

app.use('/api', createProxyMiddleware({
  target: 'http://unreachable-or-down.example',
  changeOrigin: true,
}));

app.listen(3000);
> EOF
[jrogers@Joshuas-Macbook-Pro14:/tmp/i]$ npm i http-proxy-middleware

added 19 packages in 2s

2 packages are looking for funding
  run `npm fund` for details
[jrogers@Joshuas-Macbook-Pro14:/tmp/i]$ npm i express

added 65 packages, and audited 85 packages in 2s

16 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
[jrogers@Joshuas-Macbook-Pro14:/tmp/i]$ node app.js &
[1] 23959

[jrogers@Joshuas-Macbook-Pro14:/tmp/i]$ curl 'localhost:3000/api/<>hello"'
(node:23959) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
Error occurred while trying to proxy: localhost:3000/<>hello"

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