Abhishekmishra2808 commented on code in PR #608:
URL:
https://github.com/apache/tooling-trusted-releases/pull/608#discussion_r2742275378
##########
atr/mail.py:
##########
@@ -59,28 +61,34 @@ async def send(message: Message) -> tuple[str, list[str]]:
# UUID4 is entirely random, with no timestamp nor namespace
# It does have 6 version and variant bits, so only 122 bits are random
mid = f"{uuid.uuid4()}@{global_domain}"
- headers = [
- f"From: {from_addr}",
- f"To: {to_addr}",
- f"Subject: {message.subject}",
- f"Date: {utils.formatdate(localtime=True)}",
- f"Message-ID: <{mid}>",
- ]
- if message.in_reply_to is not None:
- headers.append(f"In-Reply-To: <{message.in_reply_to}>")
- # TODO: Add message.references if necessary
- headers.append(f"References: <{message.in_reply_to}>")
-
- # Normalise the body padding and ensure that line endings are CRLF
- body = message.body.strip()
- body = body.replace("\r\n", "\n")
- body = body.replace("\n", "\r\n")
- body = body + "\r\n"
-
- # Construct the message
- msg_text = "\r\n".join(headers) + "\r\n\r\n" + body
+
+ # Use EmailMessage with Address objects for gold-standard CRLF injection
protection
+ msg = EmailMessage()
+
+ try:
+ from_local, from_domain = _split_address(from_addr)
+ to_local, to_domain = _split_address(to_addr)
+
+ msg["From"] = Address(username=from_local, domain=from_domain)
+ msg["To"] = Address(username=to_local, domain=to_domain)
+ msg["Subject"] = message.subject
+ msg["Date"] = utils.formatdate(localtime=True)
+ msg["Message-ID"] = f"<{mid}>"
+
+ if message.in_reply_to is not None:
+ msg["In-Reply-To"] = f"<{message.in_reply_to}>"
+ # TODO: Add message.references if necessary
+ msg["References"] = f"<{message.in_reply_to}>"
+ except ValueError as e:
+ log.error(f"SECURITY: CRLF injection attempt detected in email
headers: {e}")
+ return mid, [f"CRLF injection detected: {e}"]
+
+ # Set the email body (handles RFC-compliant line endings automatically)
+ msg.set_content(message.body.strip())
start = time.perf_counter()
+ # Convert to string to satisfy the existing _send_many function signature
+ msg_text = msg.as_string()
Review Comment:
Done. I have refactored the imports to follow the 'least significant name
part' convention (e.g., import email.message as emailmessage) and renamed
variables to msg to avoid conflicts.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]