-
Notifications
You must be signed in to change notification settings - Fork 96
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request from GHSA-pr2m-px7j-xg65
* SMTP Smuggling Fix Adapted adherence to RFC 5321 § 2.3.8 to fix SMTP smuggling issues (https://www.rfc-editor.org/rfc/rfc5321#section-2.3.8) * Apply suggestions from code review Co-authored-by: Sam Bull <git@sambull.org> * Add files via upload * Update test_smtpsmuggling.py --------- Co-authored-by: Sam Bull <git@sambull.org>
- Loading branch information
1 parent
b0267e8
commit 24b6c79
Showing
2 changed files
with
85 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# Copyright 2014-2021 The aiosmtpd Developers | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
"""Test SMTP smuggling.""" | ||
|
||
from email.mime.text import MIMEText | ||
from smtplib import SMTP, SMTP_SSL | ||
from typing import Generator, Union | ||
|
||
import pytest | ||
import smtplib | ||
|
||
from aiosmtpd.controller import Controller | ||
from aiosmtpd.testing.helpers import ReceivingHandler | ||
from aiosmtpd.testing.statuscodes import SMTP_STATUS_CODES as S | ||
|
||
from aiosmtpd.smtp import SMTP as Server | ||
from aiosmtpd.smtp import Session as ServerSession | ||
from aiosmtpd.smtp import Envelope | ||
|
||
from .conftest import Global, controller_data, handler_data | ||
|
||
from aiosmtpd.testing.helpers import ( | ||
ReceivingHandler | ||
) | ||
|
||
def new_data(self, msg): | ||
self.putcmd("data") | ||
|
||
(code, repl) = self.getreply() | ||
if self.debuglevel > 0: | ||
self._print_debug('data:', (code, repl)) | ||
if code != 354: | ||
raise SMTPDataError(code, repl) | ||
else: | ||
##### Patching input encoding so we can send raw messages | ||
#if isinstance(msg, str): | ||
# msg = smtplib._fix_eols(msg).encode('ascii') | ||
#q = smtplib._quote_periods(msg) | ||
#if q[-2:] != smtplib.bCRLF: | ||
# q = q + smtplib.bCRLF | ||
#q = q + b"." + smtplib.bCRLF | ||
q = msg | ||
self.send(q) | ||
(code, msg) = self.getreply() | ||
if self.debuglevel > 0: | ||
self._print_debug('data:', (code, msg)) | ||
return (code, msg) | ||
|
||
def return_unchanged(data): | ||
return data | ||
|
||
class TestSmuggling: | ||
@handler_data(class_=ReceivingHandler) | ||
def test_smtp_smuggling(self, plain_controller, client): | ||
smtplib._fix_eols = return_unchanged | ||
smtplib._quote_periods = return_unchanged | ||
smtplib.SMTP.data = new_data | ||
|
||
handler = plain_controller.handler | ||
sender = "sender@example.com" | ||
recipients = ["rcpt1@example.com"] | ||
resp = client.helo("example.com") | ||
assert resp == S.S250_FQDN | ||
# Trying SMTP smuggling with a fake \n.\r\n end-of-data sequence. | ||
message_data = b"""\ | ||
From: Anne Person <anne@example.com>\r\n\ | ||
To: Bart Person <bart@example.com>\r\n\ | ||
Subject: A test\r\n\ | ||
Message-ID: <ant>\r\n\ | ||
\r\n\ | ||
Testing\ | ||
\n.\r\n\ | ||
NO SMUGGLING | ||
\r\n.\r\n\ | ||
""" | ||
results = client.sendmail(sender, recipients, message_data) | ||
client.quit() | ||
assert b"NO SMUGGLING" in handler.box[0].content |