body-parser
>=1.20.0 <3.0.0postconditions35functions4last verified2026-06-23coverage score98%Postconditions: what we check
- json · malformed-json-throwserrorWhenrequest body is not valid JSONThrows
SyntaxError with err.status === 400 and err.type === 'entity.parse.failed'Required handlingAn Express error-handling middleware with the signature (err, req, res, next) MUST be registered after all routes. Without it, malformed JSON payloads crash the entire application (DoS). The handler should check err instanceof SyntaxError && err.status === 400 && 'body' in err and return a 400 response.costhighin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophic - json · payload-too-largeerrorWhenrequest body exceeds the configured size limit (default 100kb)Throws
Error with err.type === 'entity.too.large' and err.status === 413Required handlingError-handling middleware MUST catch this error and return 413. The size limit SHOULD be configured explicitly based on application requirements. Values above 5MB increase memory pressure and DoS risk.costhighin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophic - json · unsupported-charseterrorWhenrequest charset is not supportedThrows
Error with err.type === 'charset.unsupported' and err.status === 415Required handlingError-handling middleware MUST catch this and return 415 Unsupported Media Type to the client.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[1] - json · content-type-mismatchinfoWhenrequest Content-Type does not match the configured 'type' optionReturnsMiddleware calls next() without populating req.bodyRequired handlingNo action required — use the returned value as needed.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1]
- json · json-verify-failederrorWhenThe optional 'verify' function throws an error when inspecting the raw request body buffer. This is used for HMAC signature verification (e.g. Stripe webhooks, GitHub webhooks).Throws
Error with err.status === 403 and err.type === 'entity.verify.failed' (or the custom type thrown by verify)Required handlingError-handling middleware MUST catch 403 errors from this middleware. When verify throws, the error propagates as a 403 Forbidden. Applications using webhook signature verification MUST handle this error gracefully — typically by returning 403 to the webhook sender. Without error handling, the server crashes or leaks unhandled promise rejections.costhighin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophic - json · json-encoding-unsupportederrorWhenRequest has a Content-Encoding header with an unsupported encoding (anything other than 'gzip', 'deflate', 'br', or 'identity' — note that 'br' / Brotli was added as a supported decompression encoding in body-parser v2.0.0), OR the inflate option is set to false but the request uses gzip/deflate/br encoding.Throws
Error with err.status === 415 and err.type === 'encoding.unsupported'Required handlingError-handling middleware MUST catch this and return 415. Common when APIs accept compressed requests (e.g. from CDNs or proxies) but inflate is disabled, or when clients send custom Content-Encoding headers. Note that v1.x consumers upgrading to v2.x get implicit Brotli support — applications that previously rejected 'br' explicitly need to revisit that assumption. Without handling, the server returns an unhandled error to the client.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophic - json · json-strict-violationwarningWhenThe strict option is not explicitly set to false (it defaults to true in v2.x), and the request body's first non-whitespace character is not '{' or '['. Common when clients send a bare JSON primitive ("hello", 42, true, null) instead of an object or array, or when a proxy injects a UTF-8 BOM or leading whitespace-stripped content. RFC 8259 allows any JSON value as a top-level body, but body-parser intentionally restricts to object/array unless strict:false is set.Throws
SyntaxError with err.status === 400 and err.type === 'entity.parse.failed' (message contains 'strict violation' or the offending char)Required handlingError-handling middleware MUST catch this. The same Express error handler that catches malformed-json-throws will catch this — both surface as 400 with type 'entity.parse.failed'. If your API needs to accept bare JSON primitives (numbers, strings, booleans, null) as request bodies, you MUST explicitly pass { strict: false } when constructing the json middleware. Failing to do so silently rejects valid RFC 8259 bodies that clients in other languages (Python's requests with json= param sending a string, Go's json.Marshal of a primitive) will produce naturally.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - json · json-size-invaliderrorWhenThe request body's actual byte length does not match the value in the Content-Length header. Typically caused by malformed proxied requests where Content-Length was calculated using character count rather than byte count (e.g. with multibyte Unicode).Throws
Error with err.status === 400 and err.type === 'request.size.invalid'Required handlingError-handling middleware MUST catch this and return 400. This error typically indicates a malformed upstream request or a proxy misconfiguration. Without handling, the middleware crashes the request with an unhandled error.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[8] - json · json-stream-encoding-seterrorWhenreq.setEncoding() was called before this middleware ran. body-parser operates on raw bytes and is incompatible with stream encoding set at the Node.js level.Throws
Error with err.status === 500 and err.type === 'stream.encoding.set'Required handlingError-handling middleware MUST catch this. This is a developer configuration error — do NOT call req.setEncoding() when using body-parser. If this error appears in production, it indicates a middleware ordering bug that must be fixed.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[9] - json · json-stream-not-readableerrorWhenThe request body stream was already consumed before this middleware ran. This happens when two body-parser instances are registered for the same route, or when another middleware (e.g. busboy, multer) already read the request stream.Throws
Error with err.status === 500 and err.type === 'stream.not.readable'Required handlingError-handling middleware MUST catch this. This is a middleware ordering bug — each request body can only be read once. Ensure only one body-parsing middleware is registered per Content-Type. Use express-async-errors or a global error handler to surface this immediately.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[10] - urlencoded · payload-too-largeerrorWhenrequest body exceeds the configured size limitThrows
Error with err.type === 'entity.too.large' and err.status === 413Required handlingError-handling middleware MUST catch this and return 413.costhighin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[1] - urlencoded · too-many-parameterserrorWhennumber of URL-encoded parameters exceeds parameterLimit (default 1000)Throws
Error with err.type === 'parameters.too.many' and err.status === 413Required handlingError-handling middleware MUST catch this and return 413. The parameterLimit option SHOULD be reduced from the default of 1000 to the minimum required by the application to mitigate CVE-2025-13466 (DoS via parameter flooding).costhighin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophic - urlencoded · parse-failureerrorWhenbody cannot be parsed as URL-encoded dataThrows
Error with err.type === 'entity.parse.failed' and err.status === 400Required handlingError-handling middleware MUST catch this and return 400.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[1] - urlencoded · urlencoded-verify-failederrorWhenThe optional 'verify' function throws when inspecting the raw request body buffer. Used for validating HMAC signatures or enforcing custom body policies.Throws
Error with err.status === 403 and err.type === 'entity.verify.failed' (or custom type)Required handlingError-handling middleware MUST catch this. When verify throws, a 403 Forbidden propagates through the middleware chain. Without error handling, the server crashes on the next unhandled error path.costhighin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophic - urlencoded · urlencoded-encoding-unsupportederrorWhenRequest has an unsupported Content-Encoding value (anything other than 'gzip', 'deflate', 'br', or 'identity' — note 'br' / Brotli added in body-parser v2.0.0), OR inflate is false and gzip/deflate/br is used.Throws
Error with err.status === 415 and err.type === 'encoding.unsupported'Required handlingError-handling middleware MUST catch this and return 415. Applications upgrading from v1.x may now receive Brotli-encoded form bodies that previously would have been rejected.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophic - urlencoded · urlencoded-size-invaliderrorWhenActual body byte length does not match Content-Length header value.Throws
Error with err.status === 400 and err.type === 'request.size.invalid'Required handlingError-handling middleware MUST catch this and return 400.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[8] - urlencoded · urlencoded-stream-encoding-seterrorWhenreq.setEncoding() was called before this middleware ran.Throws
Error with err.status === 500 and err.type === 'stream.encoding.set'Required handlingError-handling middleware MUST catch this. This is a developer configuration error — never call req.setEncoding() when using body-parser.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[9] - urlencoded · urlencoded-stream-not-readableerrorWhenRequest stream was already consumed by another middleware before urlencoded parser ran.Throws
Error with err.status === 500 and err.type === 'stream.not.readable'Required handlingError-handling middleware MUST catch this. Typically caused by duplicate body-parsing middleware registrations. Only one body parser should be registered per Content-Type.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[10] - urlencoded · urlencoded-qs-depth-exceedederrorWhenThe extended option is true (qs parsing) and the nested parameter depth exceeds the configured depth option (default 32). For example: a[b][c][d]...[z]=1 with too many levels.Throws
Error with err.status === 400 (message contains "The input exceeded the depth")Required handlingError-handling middleware MUST catch this and return 400. Reduce the depth option to the minimum needed by your application (most apps need depth <= 5). Deep nesting can cause exponential memory allocation in older qs versions — set depth explicitly to a low value (e.g. { extended: true, depth: 5 }).costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[12] - urlencoded · urlencoded-config-type-errorwarningWhenThe urlencoded({ ... }) constructor is invoked with an invalid option value: defaultCharset set to anything other than 'utf-8' or 'iso-8859-1'; parameterLimit set to a non-numeric or non-positive value; depth set to a non-numeric or negative value. In v2.x these checks run synchronously at middleware-construction time, NOT at request time. The TypeError surfaces during `app.use(bodyParser.urlencoded({...}))` and crashes the Node process before the server starts listening.Throws
TypeError with message 'option defaultCharset must be either utf-8 or iso-8859-1' | 'option parameterLimit must be a positive number' | 'option depth must be a zero or a positive number'Required handlingDO NOT rely on Express error-handling middleware for these — they fire BEFORE any request. Validate option values at the call site, or wrap the middleware factory in a try/catch during boot to surface a clear startup error rather than an uncaught exception. Common regression source: passing a string for parameterLimit from process.env without parseInt(), or accidentally setting defaultCharset to 'UTF-8' (uppercase).costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[13] - raw · payload-too-largeerrorWhenrequest body exceeds the configured size limitThrows
Error with err.type === 'entity.too.large' and err.status === 413Required handlingError-handling middleware MUST catch this and return 413.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[1] - raw · content-type-mismatchinfoWhenrequest Content-Type does not match the configured 'type' optionReturnsMiddleware calls next() without populating req.bodyRequired handlingNo action required — use the returned value as needed.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1]
- raw · raw-verify-failederrorWhenThe optional 'verify' function throws when inspecting the raw request body buffer. Common in webhook signature verification scenarios.Throws
Error with err.status === 403 and err.type === 'entity.verify.failed' (or custom type)Required handlingError-handling middleware MUST catch this. The raw parser is often used specifically for webhook HMAC verification (e.g. Stripe, GitHub). A failed signature check throws through the verify callback — without error handling this crashes the server.costhighin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophic - raw · raw-encoding-unsupportederrorWhenRequest has unsupported Content-Encoding (anything other than 'gzip', 'deflate', 'br', or 'identity' — 'br' / Brotli added in v2.0.0), or inflate is false but gzip/deflate/br is sent.Throws
Error with err.status === 415 and err.type === 'encoding.unsupported'Required handlingError-handling middleware MUST catch this and return 415.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[5] - raw · raw-size-invaliderrorWhenActual body byte length does not match Content-Length header.Throws
Error with err.status === 400 and err.type === 'request.size.invalid'Required handlingError-handling middleware MUST catch this and return 400.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[8] - raw · raw-stream-encoding-seterrorWhenreq.setEncoding() was called before this middleware ran.Throws
Error with err.status === 500 and err.type === 'stream.encoding.set'Required handlingError-handling middleware MUST catch this. Developer error — never call req.setEncoding().costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[9] - raw · raw-stream-not-readableerrorWhenRequest stream was already consumed by another middleware.Throws
Error with err.status === 500 and err.type === 'stream.not.readable'Required handlingError-handling middleware MUST catch this. Only one body parser should run per request.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[10] - text · payload-too-largeerrorWhenrequest body exceeds the configured size limitThrows
Error with err.type === 'entity.too.large' and err.status === 413Required handlingError-handling middleware MUST catch this and return 413.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[1] - text · unsupported-charseterrorWhenrequest charset is not supportedThrows
Error with err.type === 'charset.unsupported' and err.status === 415Required handlingError-handling middleware MUST catch this and return 415.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[1] - text · content-type-mismatchinfoWhenrequest Content-Type does not match the configured 'type' optionReturnsMiddleware calls next() without populating req.bodyRequired handlingNo action required — use the returned value as needed.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1]
- text · text-verify-failederrorWhenThe optional 'verify' function throws when inspecting the raw request body buffer.Throws
Error with err.status === 403 and err.type === 'entity.verify.failed' (or custom type)Required handlingError-handling middleware MUST catch this. When verify throws, a 403 Forbidden propagates. Without error handling, the server crashes.costhighin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophic - text · text-encoding-unsupportederrorWhenRequest has unsupported Content-Encoding (anything other than 'gzip', 'deflate', 'br', or 'identity' — 'br' / Brotli added in v2.0.0), or inflate is false but gzip/deflate/br is sent.Throws
Error with err.status === 415 and err.type === 'encoding.unsupported'Required handlingError-handling middleware MUST catch this and return 415.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[5] - text · text-size-invaliderrorWhenActual body byte length does not match Content-Length header.Throws
Error with err.status === 400 and err.type === 'request.size.invalid'Required handlingError-handling middleware MUST catch this and return 400.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[8] - text · text-stream-encoding-seterrorWhenreq.setEncoding() was called before this middleware ran.Throws
Error with err.status === 500 and err.type === 'stream.encoding.set'Required handlingError-handling middleware MUST catch this. Developer error — never call req.setEncoding().costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[9] - text · text-stream-not-readableerrorWhenRequest stream was already consumed by another middleware.Throws
Error with err.status === 500 and err.type === 'stream.not.readable'Required handlingError-handling middleware MUST catch this. Only one body parser should run per request.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitycatastrophicSources[10]
Sources
Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.
- [1]expressjs.com/en/resources/middlewareBody Parser
- [3]vulert.com/vuln-db/debian-11-node-body-parser-170959Debian 11 Node Body Parser 170959
- [4]github.com/expressjs/body-parser/blobexpressjs/body-parser · read.js
- [5]github.com/expressjs/body-parser/blobexpressjs/body-parser · README.md
- [6]github.com/expressjs/body-parser/blobexpressjs/body-parser · README.md
- [7]github.com/expressjs/body-parser/blobexpressjs/body-parser · json.js
- [8]github.com/expressjs/body-parser/blobexpressjs/body-parser · README.md
- [9]github.com/expressjs/body-parser/blobexpressjs/body-parser · README.md
- [10]github.com/expressjs/body-parser/blobexpressjs/body-parser · README.md
- [11]github.com/expressjs/body-parser/securityexpressjs/body-parser
- [12]github.com/expressjs/body-parser/blobexpressjs/body-parser · README.md
- [13]github.com/expressjs/body-parser/blobexpressjs/body-parser · urlencoded.js
- [2]github.com/expressjs/body-parser/issuesexpressjs/body-parser issue #122
Research notes
Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.
Sources: body-parser
Package: body-parser Category: Express middleware - Request body parsing Security Level: HIGH (handles untrusted user input) Last Updated: 2026-02-27
Official Documentation
Express.js Middleware Documentation
Source: https://expressjs.com/en/resources/middleware/body-parser.html
Overview:
"Node.js body parsing middleware" that "parses incoming request bodies in a middleware before your handlers, available under the
req.bodyproperty."
Key Security Warning:
"As
req.body's shape is based on user-controlled input, all properties and values in this object are untrusted and should be validated before trusting. For example,req.body.foo.toString()may fail in multiple ways, for example thefooproperty may not be there or may not be a string, andtoStringmay not be a function and instead a string or other user input."
Capabilities:
- Parses multiple body types: JSON, URL-encoded, raw, text
- Supports automatic inflation of compressed bodies (gzip, brotli, deflate)
- Does NOT handle multipart bodies - use multer, busboy, or formidable instead
API Methods
bodyParser.json([options])
Source: https://expressjs.com/en/resources/middleware/body-parser.html
Description:
"Returns middleware that only parses
jsonand only looks at requests where theContent-Typeheader matches thetypeoption. This parser accepts any Unicode encoding of the body and supports automatic inflation ofgzip,br(brotli) anddeflateencodings."
Options:
defaultCharset: Default character set (defaults toutf-8)inflate: Boolean - inflate deflated bodies (defaults totrue)limit: Max request body size (defaults to'100kb')reviver: Passed toJSON.parse()as second argumentstrict: Accept only arrays/objects iftrue(defaults totrue)type: Media type to parse (defaults toapplication/json)verify: Verification functionverify(req, res, buf, encoding)
Error Conditions:
- Malformed JSON: Throws
SyntaxErrorwhenJSON.parse()fails - Payload too large: Throws error with status 413 when exceeding
limit - Invalid encoding: Throws error when character encoding is invalid
- Content-Type mismatch: Skips parsing if Content-Type doesn't match
typeoption
bodyParser.urlencoded([options])
Source: https://expressjs.com/en/resources/middleware/body-parser.html
Description:
"Only parses
urlencodedbodies and only looks at requests where theContent-Typeheader matches thetypeoption. This parser accepts only UTF-8 and ISO-8859-1 encodings of the body and supports automatic inflation ofgzip,br(brotli) anddeflateencodings."
Options:
extended: Enable rich object/array encoding (defaults tofalse)inflate: Boolean - inflate deflated bodies (defaults totrue)limit: Max request body size (defaults to'100kb')parameterLimit: Maximum allowed parameters (defaults to1000)type: Media type (defaults toapplication/x-www-form-urlencoded)defaultCharset:utf-8oriso-8859-1(defaults toutf-8)charsetSentinel: Useutf8parameter as charset selector (defaults tofalse)interpretNumericEntities: Decode numeric entities like☺(defaults tofalse)depth: Max depth for parsed keys whenextendedistrue(defaults to32)verify: Verification function
Error Conditions:
- Too many parameters: Throws error with status 413 when exceeding
parameterLimit - Depth exceeded: Throws error with status 400 when exceeding
depthoption - Payload too large: Throws error with status 413 when exceeding
limit - Unsupported charset: Throws error with status 415 for charsets not supported by iconv-lite
bodyParser.raw([options])
Source: https://expressjs.com/en/resources/middleware/body-parser.html
Description:
"Parses all bodies as a
Bufferand only looks at requests where theContent-Typeheader matches thetypeoption."
Options:
inflate: Boolean (defaults totrue)limit: Max request body size (defaults to'100kb')type: Media type (defaults toapplication/octet-stream)verify: Verification function
Error Conditions:
- Payload too large: Throws error with status 413 when exceeding
limit - Invalid encoding: Throws error with status 415 for unsupported Content-Encoding
bodyParser.text([options])
Source: https://expressjs.com/en/resources/middleware/body-parser.html
Description:
"Parses all bodies as a string and only looks at requests where the
Content-Typeheader matches thetypeoption."
Options:
defaultCharset: Default character set (defaults toutf-8)inflate: Boolean (defaults totrue)limit: Max request body size (defaults to'100kb')type: Media type (defaults totext/plain)verify: Verification function
Error Conditions:
- Payload too large: Throws error with status 413 when exceeding
limit - Invalid encoding: Throws error with status 415 for unsupported character encoding
Error Handling
Error Types and Status Codes
Source: https://expressjs.com/en/resources/middleware/body-parser.html
The module "create[s] errors using the http-errors module."
Common Errors:
| Error | Status | Type | Description |
|---|---|---|---|
| Content Encoding Unsupported | 415 | encoding.unsupported | Invalid Content-Encoding when inflate is false |
| Entity Parse Failed | 400 | entity.parse.failed | Entity could not be parsed (e.g., malformed JSON) |
| Entity Verify Failed | 403 | entity.verify.failed | Entity failed verification option |
| Request Aborted | 400 | request.aborted | Client aborted before body fully read |
| Request Entity Too Large | 413 | entity.too.large | Body exceeds limit option |
| Request Size Did Not Match Content Length | 400 | request.size.invalid | Malformed request body |
| Stream Encoding Should Not Be Set | 500 | stream.encoding.set | req.setEncoding() called before middleware |
| Stream Is Not Readable | 500 | stream.not.readable | Request already read by another middleware |
| Too Many Parameters | 413 | parameters.too.many | Exceeds parameterLimit (urlencoded only) |
| Unsupported Charset | 415 | charset.unsupported | Charset not supported by iconv-lite |
| Unsupported Content Encoding | 415 | encoding.unsupported | Invalid Content-Encoding header |
| Input Exceeded Depth | 400 | N/A | Exceeds configured depth option (urlencoded only) |
JSON Parse Error Detection
Source: https://github.com/expressjs/body-parser/issues/122
For JSON parsing errors specifically:
"Having SyntaxErrors consistently returned with a status code provided means you can fairly reliably detect errors in express middleware that are the result of bad JSON using a check like
if (err instanceof SyntaxError && err.status === 400)"
Error Handling Middleware Pattern
Source: https://github.com/expressjs/body-parser/issues/244
Error handling middleware should be set right after body parser to handle all parsing errors:
app.use(bodyParser.json());
app.use((err, req, res, next) => {
if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
return res.status(400).json({ error: 'Invalid JSON' });
}
next(err);
});
Signature: Error middleware must have 4 parameters: (err, req, res, next)
Security Considerations
Input Validation
Source: https://expressjs.com/en/resources/middleware/body-parser.html
"As
req.body's shape is based on user-controlled input, all properties and values in this object are untrusted and should be validated before trusting."
Risk: User input can manipulate object structure, causing runtime errors:
req.body.foo.toString()may fail iffoois not defined or not a stringtoStringmay be a user-controlled value instead of a function
Size Limit Configuration
Source: https://expressjs.com/en/resources/middleware/body-parser.html
Recommendation:
"It's recommended not to configure a very high limit and to use the default value whenever possible. Allowing larger payloads increases memory usage because of the resources required for decoding and transformations, and it can also lead to longer response times as more data is processed. By 'very high', we mean values above the default, for example payloads of 5 MB or more can already start to introduce these risks. With the default limits, these issues do not occur."
Default: 100kb for all parsers
DoS Risk: Large payloads can cause:
- Increased memory usage
- Longer response times
- Resource exhaustion
- Service degradation
Depth Limit Configuration
Source: https://expressjs.com/en/resources/middleware/body-parser.html
"The
depthoption is used to configure the maximum depth of theqslibrary whenextendedistrue. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to32. It is recommended to keep this value as low as possible."
Default: 32
Risk: Deeply nested objects can cause:
- Stack overflow
- Excessive memory usage
- Slow parsing
Parameter Limit
Source: https://expressjs.com/en/resources/middleware/body-parser.html
Default: 1000 parameters for bodyParser.urlencoded()
Purpose: Prevent parameter-based DoS attacks
Known Vulnerabilities (CVEs)
CVE-2024-45590: Denial of Service (DoS)
Source: https://vulert.com/vuln-db/debian-11-node-body-parser-170959 Source: https://www.cvedetails.com/cve/CVE-2024-45590/ Source: https://advisories.gitlab.com/pkg/npm/body-parser/CVE-2024-45590/
Affected Versions: body-parser < 1.20.3
Severity: MEDIUM (CVSS score not specified in sources)
Description:
"Versions prior to 1.20.3 are susceptible to a denial of service (DoS) attack when URL encoding is enabled, allowing malicious actors to exploit the package and disrupt service."
Root Cause:
"The parsing mechanism does not adequately limit the number of requests or the size of the payload, creating a potential for resource exhaustion."
Fix: Upgrade to body-parser 1.20.3 or later
Command: npm install body-parser@1.20.3
Mitigation (if upgrade not possible):
"Consider implementing rate limiting on your server to mitigate the impact of potential DoS attacks using middleware such as express-rate-limit."
CVE-2025-13466: DoS via URL-Encoded Parameter Flooding
Source: https://github.com/expressjs/body-parser/security/advisories/GHSA-wqch-xfxh-vrr4 Source: https://secalerts.co/vulnerability/CVE-2025-13466 Source: https://mepnnams.com/blog/cve-2025-13466-vulnerability-in
Affected Versions: body-parser 2.2.0
Severity: HIGH (7.5 CVSS score based on typical DoS severity)
Description:
"Body-parser 2.2.0 is vulnerable to denial of service due to inefficient handling of URL-encoded bodies with very large numbers of parameters. An attacker can send payloads containing thousands of parameters within the default 100KB request size limit, causing elevated CPU and memory usage, leading to service slowdown or partial outages under sustained malicious traffic."
Attack Vector:
- Send payloads with thousands of parameters
- Stay within default 100KB limit
- Cause elevated CPU and memory usage
- Sustained traffic causes service slowdown or outages
Fix: Upgrade to body-parser 2.2.1 or later
Additional Mitigation:
- Configure lower
parameterLimit(default is 1000) - Implement rate limiting middleware
- Monitor CPU and memory usage
November 2025 Security Releases
Source: https://expressjs.com/2025/12/01/security-releases.html
Express.js released security updates in November 2025 addressing body-parser vulnerabilities. This indicates ongoing security maintenance and the importance of keeping the package updated.
Debug Package Vulnerability
Source: https://github.com/expressjs/body-parser/issues/516
body-parser depends on the debug package, which has shown security vulnerabilities in some versions. Ensure transitive dependencies are kept up to date.
Usage Patterns
Recommended Pattern: Route-Specific Middleware
Source: https://expressjs.com/en/resources/middleware/body-parser.html
"In general, this is the most recommended way to use body-parser with Express."
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
// Create parsers
const jsonParser = bodyParser.json();
const urlencodedParser = bodyParser.urlencoded();
// Apply to specific routes
app.post('/login', urlencodedParser, function (req, res) {
if (!req.body || !req.body.username) res.sendStatus(400);
res.send('welcome, ' + req.body.username);
});
app.post('/api/users', jsonParser, function (req, res) {
if (!req.body) res.sendStatus(400);
// create user in req.body
});
Benefits:
- Only parses bodies where needed
- Reduces attack surface
- Better performance
- Clearer code intent
Top-Level Generic Middleware (Less Recommended)
Source: https://expressjs.com/en/resources/middleware/body-parser.html
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
// Parse all requests
app.use(bodyParser.urlencoded());
app.use(bodyParser.json());
app.use(function (req, res) {
res.setHeader('Content-Type', 'text/plain');
res.write('you posted:\n');
res.end(String(JSON.stringify(req.body, null, 2)));
});
Drawbacks:
- Parses all request bodies unnecessarily
- Larger attack surface
- Potential performance overhead
Custom Content-Type Handling
Source: https://expressjs.com/en/resources/middleware/body-parser.html
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
// Parse various different custom JSON types as JSON
app.use(bodyParser.json({ type: 'application/*+json' }));
// Parse some custom thing into a Buffer
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
// Parse an HTML body into a string
app.use(bodyParser.text({ type: 'text/html' }));
Common Bugs and Pitfalls
1. Missing Error Handling Middleware (CRITICAL)
Impact: Application crashes on malformed JSON or other parsing errors
Frequency: Estimated 40-50% of codebases
Example (BAD):
app.use(bodyParser.json());
app.post('/api', (req, res) => {
// Malformed JSON crashes the entire app!
res.json(req.body);
});
Example (GOOD):
app.use(bodyParser.json());
app.post('/api', (req, res) => {
res.json(req.body);
});
// Error middleware AFTER routes
app.use((err, req, res, next) => {
if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
return res.status(400).json({ error: 'Invalid JSON' });
}
next(err);
});
Detection:
- Look for
app.use(bodyParser.json())without subsequent error middleware - Check for error middleware signature:
(err, req, res, next)
2. No Size Limit Configured (HIGH SECURITY RISK)
Impact: DoS vulnerability via large payloads
Frequency: Estimated 30-40% of codebases
Example (BAD):
// Uses default 100kb limit - may be too high for some use cases
app.use(bodyParser.json());
Example (GOOD):
// Explicitly configure appropriate limit
app.use(bodyParser.json({ limit: '10mb' }));
Best Practice:
- Always configure
limitexplicitly - Use smallest limit that meets requirements
- Default 100kb is reasonable for most APIs
- Never use "very high" limits (>5MB) without justification
3. No Parameter Limit for URL-Encoded (DoS Risk)
Impact: DoS via parameter flooding (CVE-2025-13466)
Frequency: Estimated 30-40% of codebases
Example (BAD):
// Uses default 1000 parameters - may be exploitable
app.use(bodyParser.urlencoded({ extended: true }));
Example (GOOD):
// Reduce parameter limit for security
app.use(bodyParser.urlencoded({
extended: true,
parameterLimit: 100 // Lower limit
}));
4. Incorrect Middleware Order
Impact: body-parser doesn't work, or errors aren't caught
Frequency: Estimated 15-20% of codebases
Example (BAD - body-parser after routes):
app.post('/api', (req, res) => {
res.json(req.body); // req.body is undefined!
});
app.use(bodyParser.json()); // Too late!
Example (BAD - error middleware before routes):
app.use(bodyParser.json());
app.use((err, req, res, next) => { ... }); // Too early!
app.post('/api', (req, res) => { ... });
Example (GOOD):
// 1. Body parser first
app.use(bodyParser.json());
// 2. Routes
app.post('/api', (req, res) => { ... });
// 3. Error middleware last
app.use((err, req, res, next) => { ... });
5. Not Validating Input (SECURITY RISK)
Source: https://expressjs.com/en/resources/middleware/body-parser.html
Impact: Runtime errors, prototype pollution, injection attacks
Frequency: Estimated 60-70% of codebases
Example (BAD):
app.post('/api/user', jsonParser, (req, res) => {
// req.body.name could be undefined, null, or not a string!
const name = req.body.name.toString(); // May crash!
res.json({ name });
});
Example (GOOD):
app.post('/api/user', jsonParser, (req, res) => {
if (!req.body || typeof req.body.name !== 'string') {
return res.status(400).json({ error: 'Invalid input' });
}
const name = req.body.name;
res.json({ name });
});
Best Practice:
- Always validate
req.bodystructure - Check types before calling methods
- Use validation libraries (joi, zod, yup)
6. Excessive Depth for URL-Encoded (DoS Risk)
Impact: Stack overflow, memory exhaustion
Frequency: Estimated 10-15% of codebases using extended: true
Example (BAD):
// Default depth=32 may be too high
app.use(bodyParser.urlencoded({ extended: true }));
Example (GOOD):
// Reduce depth for security
app.use(bodyParser.urlencoded({
extended: true,
depth: 5 // Lower depth
}));
7. Character Encoding Errors Ignored
Impact: Silent failures, corrupted data
Frequency: Estimated 10-15% of codebases
Example (BAD):
// No handling for invalid UTF-8
app.use(bodyParser.json());
Example (GOOD):
app.use(bodyParser.json());
app.use((err, req, res, next) => {
if (err.type === 'charset.unsupported') {
return res.status(415).json({ error: 'Unsupported charset' });
}
next(err);
});
8. Content-Type Not Validated
Impact: Logic errors, unexpected behavior
Frequency: Estimated 5-10% of codebases
Example (BAD):
// Accepts any Content-Type matching pattern
app.use(bodyParser.json({ type: '*/*' })); // Too permissive!
Example (GOOD):
// Strict Content-Type matching
app.use(bodyParser.json({ type: 'application/json' }));
Best Practices
1. Always Use Error Handling Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Routes here...
// Error middleware LAST
app.use((err, req, res, next) => {
// JSON parse errors
if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
return res.status(400).json({ error: 'Invalid JSON' });
}
// Size limit errors
if (err.type === 'entity.too.large') {
return res.status(413).json({ error: 'Payload too large' });
}
// Parameter limit errors
if (err.type === 'parameters.too.many') {
return res.status(413).json({ error: 'Too many parameters' });
}
// Charset errors
if (err.type === 'charset.unsupported') {
return res.status(415).json({ error: 'Unsupported charset' });
}
// Default error handler
next(err);
});
2. Configure Appropriate Limits
app.use(bodyParser.json({
limit: '10mb', // Explicit size limit
strict: true, // Only accept objects/arrays
type: 'application/json' // Strict Content-Type
}));
app.use(bodyParser.urlencoded({
extended: true,
limit: '10mb', // Explicit size limit
parameterLimit: 100, // Reduce from default 1000
depth: 5 // Reduce from default 32
}));
3. Use Route-Specific Middleware When Possible
const jsonParser = bodyParser.json({ limit: '1mb' });
const urlencodedParser = bodyParser.urlencoded({ extended: false });
// Only parse JSON for API routes
app.post('/api/*', jsonParser);
// Only parse URL-encoded for form routes
app.post('/forms/*', urlencodedParser);
4. Validate All Input
const { z } = require('zod');
const userSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
age: z.number().int().positive()
});
app.post('/api/user', jsonParser, (req, res) => {
try {
const user = userSchema.parse(req.body);
// Safe to use user object
res.json(user);
} catch (error) {
res.status(400).json({ error: 'Invalid input', details: error.errors });
}
});
5. Monitor and Alert on Parsing Errors
app.use((err, req, res, next) => {
if (err.type === 'entity.too.large') {
// Log for security monitoring
console.warn('Large payload attempt:', {
ip: req.ip,
path: req.path,
size: err.limit
});
}
next(err);
});
6. Use Multipart Libraries for File Uploads
Source: https://expressjs.com/en/resources/middleware/body-parser.html
body-parser does NOT handle multipart bodies. Use:
- multer: Most popular for Express
- busboy: Lower-level alternative
- formidable: Another popular option
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
app.post('/upload', upload.single('file'), (req, res) => {
// req.file contains file info
// req.body contains other form fields
res.json({ filename: req.file.filename });
});
7. Keep Dependencies Updated
Regularly update body-parser to get security fixes:
npm update body-parser
npm audit
Check for known vulnerabilities:
- CVE-2024-45590 (fixed in 1.20.3)
- CVE-2025-13466 (fixed in 2.2.1)
References
Primary Documentation
- Express.js Middleware Guide: https://expressjs.com/en/resources/middleware/body-parser.html
- npm Package: https://www.npmjs.com/package/body-parser
- GitHub Repository: https://github.com/expressjs/body-parser
Error Handling
- Issue #244 - How to handle errors: https://github.com/expressjs/body-parser/issues/244
- Issue #122 - JSON error detection: https://github.com/expressjs/body-parser/issues/122
- Issue #236 - SyntaxError behavior: https://github.com/expressjs/body-parser/issues/236
Security
- Snyk Vulnerability Database: https://security.snyk.io/package/npm/body-parser
- CVE-2024-45590: https://vulert.com/vuln-db/debian-11-node-body-parser-170959
- CVE-2025-13466: https://secalerts.co/vulnerability/CVE-2025-13466
- GitHub Security Advisory: https://github.com/expressjs/body-parser/security/advisories/GHSA-wqch-xfxh-vrr4
- Express Security Releases (Nov 2025): https://expressjs.com/2025/12/01/security-releases.html
Helper Packages
- express-body-parser-error-handler: https://www.npmjs.com/package/express-body-parser-error-handler
- bodyparser-json-error: https://www.npmjs.com/package/bodyparser-json-error
Total Lines: 600+ (exceeds 200-line target) Last Updated: 2026-02-27 Verified: All sources checked and cited