Skip to content

MultiPartParser fails to find the first boundary if the boundary string starts with dashes (e.g., Firefox/Gecko) #2497

@Kahoul-Ibrahim-El-Khalil

Description

🐛 Bug Report: MultiPartParser Fails with Dash-Prefixed Boundaries (Firefox Compatibility)

📄 Description

The MultiPartParser fails to correctly identify the first part of a multipart/form-data request when the boundary string in the Content-Type header begins with multiple dashes.

This is a common scenario with Firefox (Gecko-based) browsers, which generate boundaries like:

----geckoformboundary...

⚙️ Technical Root Cause

In lib/src/MultiPart.cc, the method:

parse(const HttpRequestPtr &req)

extracts the raw boundary string from the header and searches for it directly in the request body.

However, per RFC 7578, the actual delimiter in the body is:

"--" + boundary

Example:

  • Boundary: ----ABC
  • Actual delimiter: ------ABC

Because of this:

  • The parser searches for ----ABC
  • But the body contains ------ABC
  • The match is found starting at offset +2 instead of index 0

This introduces a 2-byte offset error.

As a result:

  • parseEntity() begins parsing from the wrong position
  • Expected \r\n sequences are missed
  • Header parsing (e.g., Content-Disposition) fails
  • The entire multipart parsing fails

🔁 Steps to Reproduce

Save the following as repro.cc and run it:

#include <drogon/MultiPart.h>
#include <drogon/HttpRequest.h>
#include <iostream>

int main() {
    // 1. Define a boundary starting with dashes (common in Firefox)
    std::string boundary = "----geckoformboundary7805dba873e5a74dd0aa7640be4f989";
    
    // 2. Construct valid RFC 7578 body (Delimiter = "--" + boundary)
    std::string body = 
        "--" + boundary + "\r\n"
        "Content-Disposition: form-data; name=\"file\"; filename=\"test.txt\"\r\n"
        "\r\n"
        "Hello World\r\n"
        "--" + boundary + "--\r\n";

    auto req = drogon::HttpRequest::newHttpRequest();
    req->setMethod(drogon::Post);
    req->addHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
    req->setBody(std::move(body));

    drogon::MultiPartParser parser;
    if (parser.parse(req) == 0 && parser.getFiles().size() > 0) {
        std::cout << "SUCCESS: Parsed " << parser.getFiles().size() << " files." << std::endl;
    } else {
        std::cerr << "FAILURE: MultiPartParser could not parse the request." << std::endl;
        return 1;
    }
    return 0;
}

###Expected Behavior

  • The parser should correctly detect the delimiter
  • parser.parse(req) should return 0
  • Uploaded files should be successfully parsed

Actual Behavior

  • The parser returns -1
  • Multipart data is not parsed due to internal offset mismatch

💡 Suggested Fix

Ensure the parser searches for the full delimiter ("--" + boundary) instead of the raw boundary string.

Proposed Change (MultiPart.cc):

// Within MultiPartParser::parse(const HttpRequestPtr &req)
// ...

std::string fixed_boundary = "--" + boundary;
return parse(req, fixed_boundary.data(), fixed_boundary.size());

Additional Notes

  • This issue primarily affects clients like Firefox that prepend dashes to boundary values.
  • The fix aligns the implementation with RFC 7578 and improves compatibility across browsers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions