Skip to content

Commit d7d01d6

Browse files
committed
Fix CWE-190 - DoS could happen with a specially crafted boundary parameter in a multipart request
1 parent a87fcdb commit d7d01d6

2 files changed

Lines changed: 10 additions & 3 deletions

File tree

src/ESPAsyncWebServer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ class AsyncWebServerRequest {
465465
std::unordered_map<const char *, String, std::hash<const char *>, std::equal_to<const char *>> _attributes;
466466

467467
uint8_t _multiParseState;
468-
uint8_t _boundaryPosition;
468+
size_t _boundaryPosition;
469469
size_t _itemStartIndex;
470470
size_t _itemSize;
471471
String _itemName;

src/WebRequest.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,14 @@ bool AsyncWebServerRequest::_parseReqHeader() {
476476
if (value.startsWith(T_MULTIPART_)) {
477477
_boundary = value.substring(value.indexOf('=') + 1);
478478
_boundary.replace(String('"'), String());
479+
// RFC 2046 §5.1 limits boundary strings to 70 characters.
480+
// Reject invalid boundaries to prevent integer overflow in the parser.
481+
if (_boundary.length() == 0 || _boundary.length() > 70) {
482+
async_ws_log_d("Invalid multipart boundary length (%u), aborting", _boundary.length());
483+
_parseState = PARSE_REQ_FAIL;
484+
abort();
485+
return true;
486+
}
479487
_isMultipart = true;
480488
}
481489
} else if (name.equalsIgnoreCase(T_Content_Length) || name.equalsIgnoreCase(T_X_Expected_Entity_Length)) {
@@ -743,8 +751,7 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last) {
743751
itemWriteByte('\n');
744752
itemWriteByte('-');
745753
itemWriteByte('-');
746-
uint8_t i;
747-
for (i = 0; i < _boundaryPosition; i++) {
754+
for (size_t i = 0; i < _boundaryPosition; i++) {
748755
itemWriteByte(_boundary.c_str()[i]);
749756
}
750757
_parseMultipartPostByte(data, last);

0 commit comments

Comments
 (0)