Vulnerability Report: Repeated PROXY Command Causes Session Fault
Summary
The SMTP server accepts the HAProxy PROXY protocol command in the initial SMTP state. ProxyCommand.ExecuteAsync stores proxy endpoint data in context.Properties using fixed dictionary keys and returns false, intentionally preventing an SMTP state transition.
Because the state remains Initialized, a remote client can send PROXY more than once on the same connection. The second execution calls Dictionary.Add with keys that already exist, causing System.ArgumentException and faulting the session.
Impact
- Vulnerability type: remote unauthenticated denial of service against an SMTP session
- Affected component: PROXY protocol command handling
- Attack complexity: low
- Authentication required: no
- User interaction required: no
- Scope: one connection/session per trigger
Repeated connections can repeatedly force session faults and may create excessive logs, monitoring noise, and avoidable per-session exception overhead.
Affected Code
src/SmtpServer/StateMachine/SmtpStateTable.cs
src/SmtpServer/Protocol/ProxyCommand.cs
Relevant behavior:
SmtpStateTable allows ProxyCommand.Command in SmtpStateId.Initialized.
ProxyCommand.ExecuteAsync calls:
context.Properties.Add(ProxySourceEndpointKey, SourceEndpoint);
context.Properties.Add(ProxyDestinationEndpointKey, DestinationEndpoint);
return Task.FromResult(false);
Because it returns false, SmtpSession does not transition state after command execution.
Root Cause
PROXY is intended to be accepted only once and only as the first command on a connection. The implementation does not enforce this single-use invariant.
Additionally, it uses Dictionary.Add with fixed keys instead of safely rejecting a duplicate command or replacing existing values.
Expected Result
A repeated PROXY command should be rejected with a normal SMTP error response, ignored safely, or treated as a protocol violation that closes the session cleanly without an unhandled exception.
Recommended Fix
Enforce that PROXY can only be processed once per session.
Suggested approaches:
- Before adding proxy properties, check whether
ProxySourceEndpointKey or ProxyDestinationEndpointKey already exists.
- If the keys already exist, throw or return a controlled
SmtpResponseException rather than allowing Dictionary.Add to throw.
- Consider transitioning out of
Initialized after a valid PROXY command, or storing an explicit HasProxyHeader flag in the session context.
Example direction:
if (context.Properties.ContainsKey(ProxySourceEndpointKey))
{
throw new SmtpResponseException(SmtpResponse.SyntaxError);
}
context.Properties[ProxySourceEndpointKey] = SourceEndpoint;
context.Properties[ProxyDestinationEndpointKey] = DestinationEndpoint;
The exact SMTP response should match the project's protocol handling style.
Vulnerability Report: Repeated PROXY Command Causes Session Fault
Summary
The SMTP server accepts the HAProxy PROXY protocol command in the initial SMTP state.
ProxyCommand.ExecuteAsyncstores proxy endpoint data incontext.Propertiesusing fixed dictionary keys and returnsfalse, intentionally preventing an SMTP state transition.Because the state remains
Initialized, a remote client can sendPROXYmore than once on the same connection. The second execution callsDictionary.Addwith keys that already exist, causingSystem.ArgumentExceptionand faulting the session.Impact
Repeated connections can repeatedly force session faults and may create excessive logs, monitoring noise, and avoidable per-session exception overhead.
Affected Code
src/SmtpServer/StateMachine/SmtpStateTable.cssrc/SmtpServer/Protocol/ProxyCommand.csRelevant behavior:
SmtpStateTableallowsProxyCommand.CommandinSmtpStateId.Initialized.ProxyCommand.ExecuteAsynccalls:Because it returns
false,SmtpSessiondoes not transition state after command execution.Root Cause
PROXYis intended to be accepted only once and only as the first command on a connection. The implementation does not enforce this single-use invariant.Additionally, it uses
Dictionary.Addwith fixed keys instead of safely rejecting a duplicate command or replacing existing values.Expected Result
A repeated
PROXYcommand should be rejected with a normal SMTP error response, ignored safely, or treated as a protocol violation that closes the session cleanly without an unhandled exception.Recommended Fix
Enforce that
PROXYcan only be processed once per session.Suggested approaches:
ProxySourceEndpointKeyorProxyDestinationEndpointKeyalready exists.SmtpResponseExceptionrather than allowingDictionary.Addto throw.Initializedafter a validPROXYcommand, or storing an explicitHasProxyHeaderflag in the session context.Example direction:
The exact SMTP response should match the project's protocol handling style.