API Threat Model

The Threat Model of a Public API

Write down who you are defending against: the answer changes what you build. A public JSON API has four realistic attackers: a script crawling your routes for /api/users without an auth check and for id parameters it can increment; a logged-in customer reading another customer's order by changing one number in a URL; a malicious web page the victim visits, making authenticated requests with the victim's cookies; and a scraper.

Those map onto the OWASP API Security Top 10, whose 2023 edition is still current. Its first and third entries - Broken Object Level and Broken Object Property Level Authorization - are the two middleware cannot fix: only your handler knows whether u_77 may read order o_412. The rest is largely configuration.

The 2023 OWASP API risks this section addresses, and where each one is handled
OWASP API 2023 risk Concrete Express 24,430 failure Fixed in
API1/API3 object and property authorization findById(req.params.id) with no owner check 3.6.10, 3.10.5
API2 broken authentication no expiry, no lockout, tokens in URLs 3.6.5-3.6.7
API4 unrestricted resource consumption no rate limit, no body size cap 3.10.7, 3.10.5
API8 security misconfiguration no security headers, CORS set to * 3.10.2, 3.10.3

One principle ties the pipeline together: reject as early and as cheaply as possible. A request that fails a rate limit should never reach the body parser; a body over your size cap should never reach a validator; a payload that fails validation should never reach the database. Every stage you push a rejection earlier removes work an attacker can force you to do - exactly what a denial-of-service attempt is buying.

The second is less obvious: assume every defense will be misconfigured at least once. Test that the header is present, that a forged request gets a 403, that the eleventh request in a minute gets a 429 - four lines each in Supertest 14,405 (HTTP Testing with Supertest), and the only thing that notices when someone reorders app.use in a refactor.