fix(mail): sanitize the domain part of generated message-ids

generateMessageID: appended the substring following the last '@'
without sanitizing it, so a sender value such as 'Doe, John <a@b>'
produced 'Message-Id: <uuid@b>>' with a duplicated closing bracket on
calendar invitations. A nil domain also left the message-id
unterminated.

The domain part is now cut at the first address delimiter or
whitespace - a domain is a single token, and anything else would
allow header injection through generated message-ids.

Fixes #6201
This commit is contained in:
Hadrien Blanc authored and QHivert committed 2026-10-07 11:13:33 +02:00
1 parent 5e627db80d
commit 20779cf353
3 files changed
+57 -4

No files matched your search

+3 -1
View File
@@ -14,6 +14,7 @@ $(TEST_TOOL)_OBJC_FILES += \
SOGoTest.m \
SOGoTestRunner.m \
SaxXMLReaderFactory+SOGoTests.m \
../../SoObjects/Mailer/NSString+Mail.m \
\
TestVersit.m \
TestiCalTimeZonePeriod.m \
@@ -31,6 +32,7 @@ $(TEST_TOOL)_OBJC_FILES += \
TestNSString+Crypto.m \
TestNSString+URLEscaping.m \
TestNSString+Utilities.m \
TestNSString+Mail.m \
TestNSURL+misc.m \
TestNGMailAddressParser.m \
TestNGInternetSocketAddress.m \
@@ -43,7 +45,7 @@ $(TEST_TOOL)_OBJC_FILES += \
TEST_TOOL_NAME = $(TEST_TOOL)
$(TEST_TOOL)_CPPFLAGS += \
-Wall -D_GNU_SOURCE -I../../SOPE/ -I../../SoObjects/ -I../../UI/ -I../../OpenChange
-Wall -D_GNU_SOURCE -I../../SOPE/ -I../../SoObjects/ -I../../UI/ -I../../OpenChange `xml2-config --cflags`
ADDITIONAL_LIB_DIRS += \
-L../../SoObjects/SOGo/SOGo.framework/Versions/Current/sogo -L../../SOPE/NGCards/obj -L../../SOPE/GDLContentStore/obj -lSOGo -lNGMime -lNGCards -lGDLContentStore -lNGExtensions -lSBJson -lobjc \
+45
View File
@@ -0,0 +1,45 @@
#import "SOGoTest.h"
#import "Mailer/NSString+Mail.h"
static NSString *
MessageIDShape(NSString *mailOrDomain)
{
NSString *messageID = [NSString generateMessageID: mailOrDomain];
return [@"<UUID" stringByAppendingString: [messageID substringFromIndex: 37]];
}
@interface TestNSString_plus_Mail : SOGoTest
@end
@implementation TestNSString_plus_Mail
- (void) test_generateMessageID_fromAddressOrDomain
{
testEquals(MessageIDShape(@"user@example.org"), @"<UUID@example.org>");
testEquals(MessageIDShape(@"Example.ORG"), @"<UUID@example.org>");
}
- (void) test_generateMessageID_fromSenderWithDisplayName
{
testEquals(MessageIDShape(@"Doe, John <user@example.org>"), @"<UUID@example.org>");
testEquals(MessageIDShape(@"Doe, John <user@example.org> (work)"), @"<UUID@example.org>");
testEquals(MessageIDShape(@"user@example.org>"), @"<UUID@example.org>");
}
- (void) test_generateMessageID_rejectsInjectedDomains
{
testEquals(MessageIDShape(@"user@example.org\r\nBcc: victim"),
@"<UUID@example.org>");
testEquals(MessageIDShape(@"user@example.org Bcc: victim"),
@"<UUID@example.org>");
}
- (void) test_generateMessageID_withoutDomain
{
testEquals(MessageIDShape(@""), @"<UUID>");
testEquals(MessageIDShape(nil), @"<UUID>");
}
@end