-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Fix inconsistent handling of upper and lower cases of email addresses. #7021
Fix inconsistent handling of upper and lower cases of email addresses. #7021
Conversation
Heya, and thanks for this PR :) fyi matrix-org/matrix-spec-proposals#2265 mandates case folding rather than lower case conversion, so if you could update your PR to reflect that it'd be great! |
@dklimpel are you still interested in working on this? |
Yes, it is on my to do list. |
3fb29e4
to
199c1b0
Compare
de4b38a
to
61ee8a4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for this; generally it seems like a good idea.
As well as the largely minor points below, please could you update some of the tests to check that the new behaviour is working as expected at the higher level? In particular tests.rest.client.v2_alpha.test_account
looks like it tests this sort of area and would be easy to extend to cover the new code.
synapse/rest/client/v1/login.py
Outdated
# For emails, transform the address to lowercase. | ||
# We store all email addreses as lowercase in the DB. | ||
# (See add_threepid in synapse/handlers/auth.py) | ||
address = address.lower() | ||
address = canonicalise_email(address) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for the record, I have checked that there are no users on matrix.org
that will be locked out by this change (there are no users with non-ascii characters in their email addresses). I'm reasonably happy to assume that if it's not a problem on matrix.org
, it's not a problem anywhere.
better email address validation additional tests in `tests.rest.client.v2_alpha.test_account`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks very much for this, it's looking better. The new tests in particular look great!
a few comments still though, I'm afraid.
synapse/util/threepids.py
Outdated
Returns: | ||
(str) The canonical form of the email address | ||
Raises: | ||
SynapseError if the address could not be parsed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's correct that utility functions like this - which could be used anywhere - should decide what HTTP error code to return. You should raise a ValueError or similar, and turn it into a SynapseError in the rest layer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if I should catch error in auth.py
.
2786638
Co-authored-by: Richard van der Hoff <[email protected]>
stupid question, but isn't this implementation susceptible to exactly the same CVE that @clokep called out? |
Co-authored-by: Richard van der Hoff <[email protected]>
I am not sure. There is a test with https://github.com/django/django/blob/06c8565a4650b359bdfa59f9707eaa0d1dfd7223/tests/validators/tests.py#L43-L91 |
This is not a reassuring answer :/. I think its important to understand this before changing this code. I don't think the CVE is anything to do with validation. The point is: suppose |
Ok. Okay. It's clearer now. synapse/synapse/rest/client/v2_alpha/account.py Lines 124 to 132 in 35560eb
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for continuing your work on this @dklimpel !
# Get the email addresses of the user from database | ||
# The user can own more than one address. Lookup for the right address. | ||
# The email will be sent to the stored address. | ||
# It should prevent potential account hijack via password reset form, | ||
# if some compare algorithm are not exactly. | ||
addresses = await self.account_validity_handler._get_email_addresses_for_user( | ||
existing_user_id | ||
) | ||
for address in addresses: | ||
if address == email: | ||
email_from_database = address | ||
if not email_from_database: | ||
raise SynapseError(400, "Email not found", Codes.THREEPID_NOT_FOUND) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm afraid I've forgotten what we said in previous iterations of this PR, but looking at this again:
surely this is redundant and we can just send the password reset to the canonicalised address email
? get_user_id_by_threepid
will fail unless it exactly matches the email in the database?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's a double check. I'm extra careful and a little paranoid.
Should I remove the double check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it adds complication and confusion without adding much value. Yes, please remove it.
synapse/util/threepids.py
Outdated
parsedAddress = email.utils.parseaddr(address)[1] | ||
|
||
# parseaddr does not find missing "@" | ||
regex = r"^[^@]+@[^@]+\.[^@]+$" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this feels like a very complicated way to check that a string contains a single @
character? just do address.split('@')
and check the length of the result?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to change it. The function is to canonicalize and not to validate.
synapse/util/threepids.py
Outdated
address = address.strip() | ||
# Validate address | ||
# See https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11340 | ||
parsedAddress = email.utils.parseaddr(address)[1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is the object of this? email.utils.parseaddr
is not intended as a way to validate addresses, so I think it is redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You use this check in sydent: matrix-org/sydent@4e1cfff
But it does not find a missing @
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no real idea why sydent does that; I wouldn't recommend cargo-culting it. Suggest removing it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, will merge when CI completes!
* commit '5cdca53aa': Merge different Resource implementation classes (#7732) Fix inconsistent handling of upper and lower cases of email addresses. (#7021) Allow YAML config file to contain None (#7779) Fix a typo. Move 1.15.2 after 1.16.0rc2. 1.16.0rc2 Remove an extraneous space. Add links to the fixes. Fix tense in the release notes. Hack to add push priority to push notifications (#7765) Add early returns to `_check_for_soft_fail` (#7769) Use symbolic names for replication stream names (#7768) Type checking for `FederationHandler` (#7770) Fix new metric where we used ms instead of seconds (#7771) Fix incorrect error message when database CTYPE was set incorrectly. (#7760) Pin link in CHANGES.md Fixes to CHANGES.md
Fix #7016
Pull Request Checklist
EventStore
toEventWorkerStore
.".code blocks
.Signed-off-by: Dirk Klimpel [email protected]