Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions MsgReader/Outlook/Message.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2080,10 +2080,21 @@ public void Save(Stream stream)
private void SetEmailSenderAndRepresentingSender()
{
Logger.WriteToLog("Getting sender and representing sender");

// Only PR_SENDER_EMAIL_ADDRESS / PR_SENDER_SMTP_ADDRESS authoritatively identify the sender;
// other fallbacks may return the local mailbox owner's address on .msg files saved from a recipient's mailbox.
var senderEmailIsAuthoritative = false;

var tempEmail = GetMapiPropertyString(MapiTags.PR_SENDER_EMAIL_ADDRESS);
if (!string.IsNullOrEmpty(tempEmail) && tempEmail.IndexOf('@') != -1)
senderEmailIsAuthoritative = true;

if (string.IsNullOrEmpty(tempEmail) || tempEmail.IndexOf('@') == -1)
{
tempEmail = GetMapiPropertyString(MapiTags.PR_SENDER_SMTP_ADDRESS);
if (!string.IsNullOrEmpty(tempEmail) && tempEmail.IndexOf('@') != -1)
senderEmailIsAuthoritative = true;
}

if (string.IsNullOrEmpty(tempEmail) || tempEmail.IndexOf('@') == -1)
tempEmail = GetMapiPropertyString(MapiTags.PR_SENDER_SMTP_ADDRESS_ALTERNATE);
Expand Down Expand Up @@ -2175,6 +2186,25 @@ private void SetEmailSenderAndRepresentingSender()
if (string.Equals(tempEmail, tempDisplayName, StringComparison.InvariantCultureIgnoreCase))
displayName = string.Empty;

// Mailbox-owner leak guard: if the resolved e-mail came from a fallback (not authoritative) and matches a
// recipient, the .msg was saved from that recipient's mailbox; drop the e-mail and keep just the display name.
if (!senderEmailIsAuthoritative
&& !string.IsNullOrEmpty(email)
&& email.IndexOf('@') != -1
&& _recipients != null)
{
foreach (var recipient in _recipients)
{
if (!string.IsNullOrEmpty(recipient?.Email)
&& string.Equals(recipient.Email, email, StringComparison.OrdinalIgnoreCase))
{
Logger.WriteToLog($"Discarding non-authoritative sender e-mail '{email}' because it matches a message recipient (mailbox-owner leak)");
email = string.Empty;
break;
}
}
}

// Set the representing sender if it is there
Sender = new Sender(email, displayName);
var representingAddressType = GetMapiPropertyString(MapiTags.PR_SENT_REPRESENTING_ADDRTYPE);
Expand Down