Skip to content
Permalink
Browse files

Require that parsed mail addresses match raw input

Python's email parser turns malformed addresses into valid ones
by removing anything after and including the second '@'. This
meant that sydent sent emails to the validated address but stored
the raw address as validated.

This rejects any requests where the parsed email address does not
match the raw input.
  • Loading branch information...
dbkr committed Apr 18, 2019
1 parent 617ff31 commit 4e1cfff53429c49c87d5c457a18ed435520044fc
Showing with 11 additions and 5 deletions.
  1. +11 −5 sydent/util/emailutils.py
@@ -55,12 +55,13 @@ def sendEmail(sydent, templateName, mailTo, substitutions):
allSubstitutions[k+"_forhtml"] = cgi.escape(v.decode('utf8'))
allSubstitutions[k+"_forurl"] = urllib.quote(v)

mailString = open(mailTemplateFile).read() % allSubstitutions
rawFrom = email.utils.parseaddr(mailFrom)[1]
rawTo = email.utils.parseaddr(mailTo)[1]
if rawFrom == '' or rawTo == '':
mailString = open(mailTemplateFile).read().decode('utf8') % allSubstitutions
parsedFrom = email.utils.parseaddr(mailFrom)[1]
parsedTo = email.utils.parseaddr(mailTo)[1]
if parsedFrom == '' or parsedTo == '':
logger.info("Couldn't parse from / to address %s / %s", mailFrom, mailTo)
raise EmailAddressException()

mailServer = sydent.cfg.get('email', 'email.smtphost')
mailPort = sydent.cfg.get('email', 'email.smtpport')
mailUsername = sydent.cfg.get('email', 'email.smtpusername')
@@ -77,7 +78,12 @@ def sendEmail(sydent, templateName, mailTo, substitutions):
smtp = smtplib.SMTP(mailServer, mailPort, myHostname)
if mailUsername != '':
smtp.login(mailUsername, mailPassword)
smtp.sendmail(rawFrom, rawTo, mailString.encode('utf-8'))

# We're using the parsing above to do basic validation, but instead of
# failing it may munge the address it returns. So we should *not* use
# that parsed address, as it may not match any validation done
# elsewhere.
smtp.sendmail(mailFrom, mailTo, mailString.encode('utf-8'))
smtp.quit()
except Exception as origException:
twisted.python.log.err()

3 comments on commit 4e1cfff

@myselfhimself

This comment has been minimized.

Copy link

replied Apr 23, 2019

How is this a fix... as shown also here https://bugs.python.org/msg329463 ?
Following the Python RFC here you should check for parsedFrom == ('', '') and same for parsedTo == ('', '')

@myselfhimself

This comment has been minimized.

Copy link

replied Apr 23, 2019

Don't you want to check mailFrom != parsedFrom and mailTo != parsedTo as stated in "This rejects any requests where the parsed email address does not match the raw input." ?

@kstefanini

This comment has been minimized.

Copy link

replied Apr 26, 2019

Please sign in to comment.
You can’t perform that action at this time.