From 0b6e845cf04012ce22f0ddadeea9e24e72de1054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Eorvaldur=20Hafdal?= Date: Wed, 15 Jul 2026 11:25:21 +0000 Subject: [PATCH] SS-3 Fix PROXY TCP version validation --- src/SmtpServer.Tests/SmtpParserTests.cs | 18 ++++++++++++++++++ src/SmtpServer/Protocol/SmtpParser.cs | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/SmtpServer.Tests/SmtpParserTests.cs b/src/SmtpServer.Tests/SmtpParserTests.cs index 555093cd..08056dd8 100644 --- a/src/SmtpServer.Tests/SmtpParserTests.cs +++ b/src/SmtpServer.Tests/SmtpParserTests.cs @@ -312,6 +312,24 @@ public void CanMakeProxyTcp6() Assert.Equal(16789, ((ProxyCommand)command).DestinationEndpoint.Port); } + [Theory] + [InlineData("PROXY TCP5 192.168.1.1 192.168.1.2 1234 16789")] + [InlineData("PROXY TCP46 192.168.1.1 192.168.1.2 1234 16789")] + [InlineData("PROXY TCPA 192.168.1.1 192.168.1.2 1234 16789")] + public void CanNotMakeProxyWithInvalidTcpVersion(string input) + { + // arrange + var reader = CreateReader(input); + + // act + var result = Parser.TryMakeProxy(ref reader, out var command, out var errorResponse); + + // assert + Assert.False(result); + Assert.Null(command); + Assert.Null(errorResponse); + } + [Fact] public void CanMakeAtom() { diff --git a/src/SmtpServer/Protocol/SmtpParser.cs b/src/SmtpServer/Protocol/SmtpParser.cs index 3b57b32c..857eb84d 100644 --- a/src/SmtpServer/Protocol/SmtpParser.cs +++ b/src/SmtpServer/Protocol/SmtpParser.cs @@ -845,7 +845,7 @@ public bool TryMakeTcp4Proxy(ref TokenReader reader, out SmtpCommand command) } var token = reader.Take(); - if (token.Kind != TokenKind.Number && token.Text[0] != '4') + if (token.Kind != TokenKind.Number || token.Text.Length != 1 || token.Text[0] != '4') { return false; } @@ -869,7 +869,7 @@ public bool TryMakeTcp6Proxy(ref TokenReader reader, out SmtpCommand command) } var token = reader.Take(); - if (token.Kind != TokenKind.Number && token.Text[0] != '6') + if (token.Kind != TokenKind.Number || token.Text.Length != 1 || token.Text[0] != '6') { return false; }