Add 8KB body size limit to JSON POST endpoints to prevent heap exhaustion#798
Open
blade-running-man wants to merge 1 commit intoBlueforcer:mainfrom
Open
Add 8KB body size limit to JSON POST endpoints to prevent heap exhaustion#798blade-running-man wants to merge 1 commit intoBlueforcer:mainfrom
blade-running-man wants to merge 1 commit intoBlueforcer:mainfrom
Conversation
POST endpoints that parse JSON bodies have no size limit, allowing a single request to allocate unbounded memory via ArduinoJson and potentially cause an OOM crash on the ESP32. Add isBodyOversized() guard that rejects payloads over 8KB (matching MQTT_MAX_PACKET_SIZE) with 400 Bad Request. Applied to endpoints that parse JSON: /api/moodlight, /api/notify, /api/apps, /api/settings, /api/reorder, /api/custom, /api/indicator1-3. Not applied to /api/power, /api/rtttl, /api/sound, /api/r2d2 which accept small plain-text or URL-encoded payloads. Reproduce: curl -X POST http://<ip>/api/notify -d @large_file.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
POST endpoints that parse JSON (
/api/notify,/api/custom,/api/indicator1-3, etc.) have no payload size limit. Sending a large payload causes ArduinoJson to allocate unbounded memory viaDynamicJsonDocument, exhausting the ESP32 heap. After a few oversized requests, even normal-sized requests start failing with500 ErrorParsingJsonbecause there is not enough free heap left.Root cause
The WebServer reads the full request body into
arg("plain")regardless of size, then each handler passes it directly to ArduinoJson for parsing. ArduinoJson allocates roughly1.3xthe input size for its internal document. On an ESP32 with ~200KB free heap, a single 32KB payload can consume a significant portion of available memory, and the fragmentation left behind can prevent subsequent allocations from succeeding.Fix
Add a static
isBodyOversized()helper that checksarg("plain").length() > 8192before any JSON parsing. If the body exceeds 8KB, the handler immediately returns400 Bad Requestwithout allocating aDynamicJsonDocument.The 8KB limit matches the existing
MQTT_MAX_PACKET_SIZE(defined inplatformio.ini), so HTTP and MQTT have the same maximum payload size.Guarded endpoints (parse JSON):
/api/moodlight,/api/notify,/api/apps(POST),/api/settings(POST),/api/reorder,/api/custom,/api/indicator1,/api/indicator2,/api/indicator3Not guarded (plain-text / small payloads):
/api/power,/api/sleep,/api/rtttl,/api/sound,/api/r2d2,/api/switchHow to reproduce
Test script
Before (main branch, firmware 0.98)
After sending oversized payloads, the device enters a degraded state where even valid requests fail until reboot.
After (this branch)