Unauthenticated OOM Denial of Service via incoming SMTP connections

Issue Description

Stalwart does not dynamically limit the memory usage of incoming SMTP messages. As a result, multiple concurrent slow connections can exhaust the server’s available RAM, crashing the mail server via the OS OOM killer.

This behavior can be weaponized to perform a Denial of Service attack against Stalwart instances.

I previously reported this to Stalwart Security, who classified the behavior as a configuration issue rather than a software vulnerability. Because the default configuration leaves instances susceptible to this resource exhaustion, I am sharing the disclosure here for community awareness so other administrators can adjust their setups accordingly.

Full Disclosure and PoC are publicly available at: GitHub - sergiogarciadev/stalwart-slowsender: Denial of Service Full Disclosure Report · GitHub

Expected Behavior

The email server should spool payloads to disk or limit inbound connection memory usage to prevent exceeding maximum available RAM.

Actual Behavior

The mail server crashes.

Reproduction Steps

Full reproductions steps are available in the Public Full Disclosure.

Stalwart Version

v0.16.x

Installation Method

Docker

Database Backend

SQLite

Blob Storage

SQLite

Search Engine

Internal

Directory Backend

Internal

Additional Context

This was previously reported to [email protected] and classified by the team as a configuration issue that should be handled by adjusting max_message_size and max_connections.

I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.

on

I have searched this support forum (open and closed topics) and confirm this is not a duplicate.

on

I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.

on

I have enough to give a grounded, actionable reply pointing to the relevant mitigations documented for Stalwart.

Thanks for the writeup and for sharing the PoC responsibly. This lines up with how Stalwart’s security team classified it: the server exposes several knobs specifically meant to bound per-connection and server-wide resource consumption, and the defaults are intentionally permissive rather than hardened, so operators are expected to tune them for their exposure.

Relevant settings for mitigating slow-sender/OOM-style abuse:

  • SystemSettings.maxConnections – server-wide cap on concurrent connections (default 8192), and each NetworkListener can set its own maxConnections to cap a specific SMTP port independently. (docs/server/listener.md)
  • MtaInboundSession (Settings → MTA → Inbound → Session) exposes maxDuration (max session length, default 10m), timeout (max time to wait for a client command before disconnecting, default 5m), and transferLimit (max bytes transferred per session, default ~250MB). Lowering timeout sharply reduces how long a “slow-sender” can hold a connection open. (docs/ref/object/mta-inbound-session)
  • MtaStageData.maxMessageSize – caps a single message’s size (default 100MB). (docs/mta/inbound/data.md)
  • MtaInboundThrottle objects let you rate-limit or cap concurrency per remote IP/subnet for inbound SMTP sessions, which is the direct countermeasure for many slow connections opened from the same source. (docs/mta/outbound/rate-limit.md, “Inbound limits”)
  • loiterBanRate/loiterBanPeriod under Security auto-ban connections that repeatedly connect without sending meaningful traffic. (docs/server/auto-ban.md)

Tightening timeout/maxDuration on MtaInboundSession, adding a per-IP MtaInboundThrottle limiting concurrent connections, and lowering maxConnections on the SMTP listener together close most of the exposure described in your PoC.

DATA stage | Stalwart and MtaInboundSession | Stalwart

This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.

Note that your CVE will be contested. Anyone with an LLM is a security researcher nowadays and we’re a bit tired of it.

Ok, I understand your frustration and all security community frustration with LLM reports.

Please note that I found this because I was conducting the due diligence on the project because I am now using it for my own needs.

I spent significant amount of time isolating a PoC and making it as reproducible as possible.

I don’t make a living from security but I have helped community in projects that I use dating back 15 years ago (GitHub - sergiogarciadev/HashCollisionDetector: Detect Hash Colisions Attach on ASP .net · GitHub).