expressjs / expressjs/discussions

Proposal: Security Documentation Improvements

Open
#522 5 comments 1 reaction 0 assignees View on GitHub
Dominant language
No language data
Stars
73
Forks
25
PR merge metrics
No merged PRs in 30d

Description

# Proposal: Security Documentation Improvements
This is the Proposal deliverable for our Sovereign Tech Agency contract, Milestone 8 (Security Documentation).
This proposal is just over 1k words and like ~4 min of read time?

The audit of the website security content I conducted (with help from Claude) is [here](https://gist.github.com/jonchurch/88e462ae991db7360b9c723b4c777ea9)

cc @bjohansebas @crandmck I opened this on the Discussions repo since its a top level proposal associated with STA, to get TC input, and also, tbh, to hopefully prevent a flood of AI generated PRs from folks trying to implement this plan for us 🙃

## What's Wrong

Today there is no comprehensive, highly visible, single place on the website to learn about securing an Express application.

Our best resource is buried under Docs > Advanced > Security Best Practices, but its coverage does not extend even to the most common pitfalls within the framework's API itself.

Here are some headline findings in that vein from [an audit of the site's security content](https://gist.github.com/jonchurch/88e462ae991db7360b9c723b4c777ea9):

* Today there is a single ["Production Best Practices: Security"](https://expressjs.com/en/advanced/best-practice-security/) page, which has not been meaningfully updated since 4.x (e.g. it opens with a note stating 2.x and 3.x are no longer maintained, and links folks to the 4.x migration guide instead of the 5.x).
* It is a decent starting place of best practices, but reads as more of a grab bag of things rather than a comprehensive guide to using the framework securely.
* There is a [Security Updates](https://expressjs.com/en/advanced/security-updates/) page, but it stops in December 2024 at v4.21.2, and has no 5.x section (it has a 3.x section!)
* Currently, our [security release blog posts authored by Ulises](https://expressjs.com/en/blog/2026-08-31-security-releases/) are the only place on the website where we list security updates for our ecosystem of packages. Security updates for express itself and other packages are intermingled in these posts.
* The API reference content has inconsistent warnings about security implications when there are footguns in the API which are not obvious from the call signature itself. Inconsistent in that some warnings exist, notably for [req.query](https://expressjs.com/en/5x/api/request/#reqquery), [req.body](https://expressjs.com/en/5x/api/request/#reqbody), [app.locals](https://expressjs.com/en/5x/api/application/#applocals), but no warnings about e.g. express.static.
* Consider that our Threat Model states it is the user's responsibility to correctly configure express.static, but the API Reference for it makes no note of footguns there.
* We miss the opportunity, for example, to tell users when some method's arguments must not come from user input. `res.render`'s view name is an example, it becomes a filesystem path and can trigger a `require`. We say that on `app.render` but not `res.render`.

## What We Will Build

I am proposing 5 things to make it much simpler for folks to build more secure Express applications, improve the security posture of existing applications, and stay up to date with important security updates to Express.

### A Security Hub Page `expressjs.com/security`

Provide users with a single checklist style page they can visit to get the basic guidance from the maintainers/community on how to secure an Express application. Ideally each formed as a yes/no question.

This is the "Hub" of a "Hub and Spoke" model. The Hub page is meant to link out to pages which better explain each item on the checklist.

Example: "Is `trust proxy` set to match your deployment, and never `true` if a client's own `X-Forwarded-For` header can reach your app? _Link to a page about Running Behind a Proxy_"

### Topic Pages under `expressjs.com/security/`

These are mostly the spokes of the Hub and Spoke model.

More comprehensive pages as resources for folks who want to learn more about a given topic in the hub checklist. Not all of this content is net new for the site, but organizing it and standardizing it will likely require rewriting a lot of things.

Priority 1 topics would include things which are specific to Express and its APIs:
* proxies and trust proxy setting
* handling untrusted input (request side sources like querystrings, body, params)
* response sinks (send, redirect, render, cookie)
* routing and middleware order
* serving files
* error handling without leaking information
* resource exhaustion (request size limits, timeouts, uploads)

Lower Priority topics for comprehensive coverage. These priority rankings are debatable. We realistically have to put a cut line somewhere, and "things not shipped by default in the framework" is the cleanest cut I can think of.
* CORS
* sessions
* CSRF
* ...probably a lot more

### API Reference Notes

Commit to warning users in the API reference when passing user input as an argument is a known footgun.

I'm aware currently of needing updates for `res.sendFile`, `res.download`, `res.render`, `express.static` plus whatever else we turn up. The goal here is to set a precedent that if we _know_ something can easily be a footgun when using direct user input we warn users in the API reference.

Setting that rule is important, and something we can lean on the community to help keep us consistent with.

I stop short of any other rule here about Warnings on API reference docs, this is something I'm looking for feedback on. As in, we need better rules for when we add a Warning or other security note, lest we fatigue people by telling them "`res.send` can do dangerous things if you send HTML to the user!"

### Security Updates Page

Revive the security updates page! We need a 5.x section for Express specific patches to CVEs we have issued.

Ulises is already doing great work compiling our security release information in the blog. We should ensure there is an easy place where folks can check for these updates, and link back to the blog post.

The page should track the `express` package and the direct dependencies we ship with it.

### Clean Up The Mess We Will Make

These changes will make some information redundant. We should clean up those references and link into their new homes where appropriate, as well as remove information or guides that are out of date.

I am specifically calling out that we should drop the existing [`expressjs.com/advanced/best-practice-security`](https://expressjs.com/en/advanced/best-practice-security/) page, and set up a redirect to the new location.

## Implementation Plan

I'll begin opening PRs to the expressjs.com repo after this proposal sits for a week for feedback (so targeting September 18th).

I plan to author the first versions of the content outlined above, with reviews and edits by Rand and the community.

The target is English content merged by September 30th, translations follow through the existing Crowdin translation pipeline after the English content lands.

## Please Give Me Feedback

Happy to hear your feedback, but these questions below I'd like answered before I start opening PRs, the rest I consider settled enough to begin this work. We can always perfect this work in the future.

Specifically I am wondering:
1. What should we set as the bar for adding a security note (like a `Warning` infobox or similar) to an API reference entry? I suggested in this proposal "when passing user input as an argument is a known footgun"
2. On the Security Updates page, should we track only express and its top level deps? Or should it track the wider umbrella of packages? I lean express plus direct deps only.
3. What other specific Express footguns am I missing in the topic list?

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the existing expressjs.com/en/advanced/best-practice-security/ and Security Updates pages, the linked security-content audit, and the cited API reference entries such as req.query, res.render, and express.static. The work is done when the scope and security-note rules are agreed, the proposed hub and topic content is merged, updates are organized, and outdated references redirect to the new location.

Written by the indexing model from the issue text.

Assessment

Tech stack
express
Domain
documentation, security
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.