Express 4.16.0 express.static broken for filename

I’m opening this issue to discuss and / or talk about an issue that has been reported twice (that I know of, at the time of opening this issue) so far regarding a change of behavior in express.static in Express 4.16.0 release.

In Express.js 4.16.0 there is a change in express.static that shouldn’t cause issues (assuming correct API usage) but mitigates Express.js apps from the Node.js path validation vulnerability.

After tracking it down, it turns out there may be some apps (I don’t know how common / uncommon yet) that were providing a file name as the first argument of express.static instead of a file path. This combined with a app.use path that would match the entire URL (like /* for example) seems to have been accidentally serving that file to all URLs in prior Express.js versions.

If this change broke you app, first, we apologize; the API has never worked or been documented this way so we had no idea that this is something that worked and thus also had zero tests for this kind of combination.

The first argument for express.static (which is the serve-static module) is document as the name root with the following description:

The root argument refers to the root directory from which the static assets are to be served.

I 100%% understand that documentation can be terse and that working is working, so please don’t take that as an excuse, just a post-mortem to the situation.

If you are in a situation where you can modify your app, the best thing you can do is use res.sendFile in a middleware instead of express.static for this specific case.

For example, change

app.use('/*', express.static('path/to/file.html'))

to

app.use('/*', (req, res) => res.sendFile(path.resolve('path/to/file.html'))

We would like to better understand the impact of this (if any) to evaluate if there needs to be a follow up patch release to get the above use-case back to working. It’s possible there could be another odd use-case that doesn’t work as well, so it may be whack-a-mole, which is why using the correct APIs is definitely the best course of action.

If you were impacted by this change, let us know here. Even if you took the action of changing to res.sendFile, feel free to also let us know anyway (noting that you changed your app), which can help act as a proxy for the silent users as well for impact evaluation.

Author: Fantashit

4 thoughts on “Express 4.16.0 express.static broken for filename

  1. This issue has impacted my team. We support dozens of Express apps that service tens of millions of users every day. Our deployments are currently dead in the water until we can go into every app and pin Express to a previous version.

    PLEASE consider releasing a hotfix for this ASAP.

  2. If we could simply revert the change, we would, but that would undo the security vulnerability patch it brings. Without the patch, a remote user can access any file on your file system. We are looking into an alternative method of fixing this that would restore the API mis-use of express.static and still keep your servers protected.

  3. A fix is on the way through the dependencies and an Express 4.16.1 will be released today with the fix. It should function exactly as it used to, we’re not going to warn or anything at this time, just get it back to working as-is.

  4. Waiting for the CI to come back green and then 4.16.1 will be released. Thanks again for the feedback everyone. I’m sorry this d=caused some disruption during the upgrade, and hope you can see that we value the stability of Express, and take even disruptions of weird edge cases like this seriously 🙂 I hope you continue to enjoy Express!

Comments are closed.