---
id: "GHSA-39q9-qp46-w8xg"
page: "https://infrastack.ai/live/GHSA-39q9-qp46-w8xg"
kind: "vulnerability"
aliases: ["GHSA-39q9-qp46-w8xg"]
title: "`bodyLimit()` keeps every transfer chunk of a request body in memory, allowing memory exhaustion with tiny chunks"
severity: "medium"
cvss: 5.3
epss: null
exploited: false
status: "open"
category: "package"
products: [{"name": "hono", "fixed": ["4.13.18"], "affected": ">= 4.12.16, <= 4.13.17", "ecosystem": "npm"}]
ecosystems: ["npm"]
tags: ["bun", "cwe-400", "hono", "node", "package", "self-hosted"]
not_affected_if: ["no-bodylimit", "version-outside-range"]
published_at: "2026-11-11T08:54:36+00:00"
first_seen_at: "2026-11-11T08:59:08+00:00"
updated_at: "2026-11-11T09:01:18+00:00"
sources: [{"source": "ghsa-repo", "url": "https://github.com/honojs/hono/security/advisories/GHSA-39q9-qp46-w8xg", "first_seen_at": "2026-11-11T08:59:08+00:00"}]
exploit_sources: []
---

# `bodyLimit()` keeps every transfer chunk of a request body in memory, allowing memory exhaustion with tiny chunks

Link for people: https://infrastack.ai/live/GHSA-39q9-qp46-w8xg (this .md is for agents)

Hono's bodyLimit() middleware from 4.12.16 stores each transfer chunk of a request body as a separate object before the handler runs. A single unauthenticated request sending the body in very small chunks can use many times its size in memory and crash the process.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- npm:hono affected >= 4.12.16, <= 4.13.17 fixed 4.13.18

## How to check

- Check the installed version with `npm ls hono` and confirm it is between `4.12.16` and `4.13.17`.
- Search the codebase for `bodyLimit(` to see whether the middleware is used.

## Fix

- `hono` moves to `4.13.18` (fixed version per the advisory data).

## Timeline

- 2026-11-11T08:59:08+00:00 ghsa-repo https://github.com/honojs/hono/security/advisories/GHSA-39q9-qp46-w8xg

## Documents

- [advisory] Maintainer's advisory: github.com https://github.com/honojs/hono/security/advisories/GHSA-39q9-qp46-w8xg

## From the sources

### Summary

Since 4.12.16, `bodyLimit()` reads the whole request body before the handler runs so that the limit also applies to chunked requests. It kept every chunk delivered by the runtime as a separate array and later replayed them. A client that sends the body in very small transfer chunks makes the middleware retain millions of small arrays for a body that is within the configured limit. The memory used is many times the body size, and the process can be terminated before the handler runs.

### Details

The size check counted the payload bytes correctly, so the configured `maxSize` was respected. The problem is the per-chunk overhead: each `Uint8Array` the runtime delivers was kept as its own object until the body was complete, then enqueued again into a new stream. With one-byte HTTP transfer chunks, a 10 MiB upload becomes about ten million retained objects.

`bodyLimit()` now copies the incoming chunks into one buffer that grows up to `maxSize`, and forwards that buffer as the request body. Memory use is bounded by the configured limit regardless of how the body is chunked.

Observed on Bun and Node.js, where the HTTP parser delivers transfer chunks as they arrive.

### Impact

An unauthenticated client can exhaust the memory of a server that uses `bodyLimit()` with a single request that stays within the configured limit, terminating the process.

This issue affects applications that use `bodyLimit()` on runtimes that deliver small transfer chunks individually, such as Bun and Node.js.

---

_Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai_
