Roundup Tracker - Issues

Issue 2550716

classification
Email address displayed after password reset request
Type: security Severity: normal
Components: Web interface Versions: 1.4
process
Status: fixed fixed
:
: rouilj : ThomasAH, ber, ezio.melotti, luke, rouilj
Priority: normal :

Created on 2011-08-05 10:00 by luke, last changed 2020-08-29 04:27 by rouilj.

Messages
msg4358 Author: [hidden] (luke) Date: 2011-08-05 10:00
Roundup allows you to request a password reset request
(/user?@template=forgotten). After stating an username Roundup confirms
this request with "Email sent to EMAILADRESS". This allows to tap addresses.

My rfe would be to change this to "Email send to USER@..." (by omitting
the domain) or simply "Email with password request has been sent."
msg4367 Author: [hidden] (ber) Date: 2011-08-11 10:54
Hi Luke,
thanks for the feedback.

Can you explain to me a bit more, how that "taping" of emails
is raising the risk? I mean, if you at all can tap the emails of the 
roundup-server, you'd probably would just tap all of them. And often 
you might already have an idea about the corresponding email domain of 
some users.
msg4564 Author: [hidden] (ezio.melotti) Date: 2012-05-22 00:35
FWIW this has been reported at
http://psf.upfronthosting.co.za/roundup/meta/issue430 too.
msg4568 Author: [hidden] (ber) Date: 2012-05-22 07:53
Ezio, thanks for linking!
At least Loewis also seems to think that this is not an issue,
but a feature.

What is your take on the issue?
msg4703 Author: [hidden] (ThomasAH) Date: 2012-12-18 14:42
Bernhard, in msg4367 you seem to think that someone needs to get hold of
the sent mail to retrieve the address.
Clarification:
The email address is displayed as "Email sent to user@example.com" in
the web interface, even when just the username was entered in the
password reset form.

I consider this an information leak as it does not even use the
permission system, therefore upgrading to type security and severity
normal. I would even think that a higher severity level might be
appropriate.
msg5760 Author: [hidden] (rouilj) Date: 2016-07-05 23:58
See also http://psf.upfronthosting.co.za/roundup/meta/issue430

With the patch in current head for:

- allow user to recover account password using an entry in the
  Alternate E-mail addresses list. See:
     http://psf.upfronthosting.co.za/roundup/meta/issue564
  for description. Merge request at:
    https://sourceforge.net/p/roundup/code/merge-requests/1/

I wonder if obscuring the email like:

   rouilj@cs.*******.com

would provide enough to allow the user to determine
the address that was emailed, but not enough to allow
harvesting of emails?

Thoughts?
msg5774 Author: [hidden] (ThomasAH) Date: 2016-07-07 09:17
Of course there is always the discussion of "do we want to confirm that
an account with this name exists?" Moin wikis just say "If this account
exists an email was sent.".

This sometimes is really annoying, so I would prefer to only have this
as an option (if at all), not the default, as the default behaviour of
roundup is a public tracker, even if we mostly use non-public trackers.

To make the obfuscation yield more privacy, I suggest obfuscating more,
especially in the username part, as this often includes the real name of
people.

What about replacing everything with dots, except for the first
character of the localpart, the @ and the last character of the domain
(and the dots :)), e.g.:

user@example.com -> u...@..........m
user@example.net -> u...@..........t
firstname@example.com -> f........@..........m ->
firstname.lastname@ntvtn.de -> f.................@.......e
msg5775 Author: [hidden] (rouilj) Date: 2016-07-07 12:01
Hi Thomas:

In message <1467883027.57.0.0387948914625.issue2550716@psf.upfronthosting.co.za
>,
Thomas Arendsen Hein writes:
>
>Of course there is always the discussion of "do we want to confirm that
>an account with this name exists?" Moin wikis just say "If this account
>exists an email was sent.".

There can be multiple emails associated with the account. We need to
give the user some indication which email was used to send the
recovery password so they can choose one of the alternate addresses
associated with the account to receive the password reset email. (That
was the feedback from the ticket that I closed to provide the ability
to send a reset email to an alternate address.)

Also the user has the option of specifying the email address they want
the recovery password sent to. If they specified an email address,
should we mask it?

Should we return an error if the user supplies an invalid lookup email
address rather than a username? I think my answer is no don't return
an error but...

However we probably should always provide a positive response even if
the username they asked for is invalid. Asking for a reset for the
user "donny" who doesn't exist should result in:

   Email has been sent to d**ny@rx*****.**m

The domain part of the result can be made up from random words/chars.

>This sometimes is really annoying, so I would prefer to only have this
>as an option (if at all), not the default, as the default behavior of
>roundup is a public tracker, even if we mostly use non-public trackers.

Agreed, it will be an tracker option maybe:

     mask_recovery_email = yes/no

or even:

     recovery_email_mask_character = *

default not set and no masking happens. If set to a character, masking
happens using that character.

>To make the obfuscation yield more privacy, I suggest obfuscating more,
>especially in the username part, as this often includes the real name of
>people.
>
>What about replacing everything with dots, except for the first
>character of the localpart, the @ and the last character of the domain
>(and the dots :)), e.g.:
>
>user@example.com -> u...@..........m
>user@example.net -> u...@..........t
>firstname@example.com -> f........@..........m ->
>firstname.lastname@ntvtn.de -> f.................@.......e

I am worried that that is too little info. I was trying to find a mask
that displays places where there is likely to be a lot of variation in
the unmasked bits. But still making enough to prevent somebody who
won't know the original input from making an email address from
it. Hence trying to include a couple of bytes of info around both
sides of the @ sign.

I think if we can get a mask that allows for 5-10 plausible variations
in email addresses we have done our job.

If it's a targeted attack against a specific user where the attacker
has a lot of background knowledge, anything that would be useful to
the actual account owner will also be useful to the attacker so...

Also I think losing the structure of the email address (i.e. what is a
. in the address vs. what is a masking dot) is a problem as well, but
setting a different "masking_character" config option allows the
tracker admin to choose.

Maybe

  user@example.com -> u.er@ex........m
  user@example.net -> u.er@ex........t
  firstname@example.com -> f......me@ex........m ->
  firstname.lastname@ntvtn.de -> f...............me@nt.....e

I have the same username at most places. The start of the domain spec
is where the high entropy bits are located for my addresses.

Thoughts?
msg5781 Author: [hidden] (ber) Date: 2016-07-08 06:38
Overall I believe that we should not indicate the email address or its 
existence. Nor should be indicate if this is a valid user name.

What about: Sending an email reset possibility email to all email addresses?
In case you are not getting an email, all you can do is register again
or contact the admins.
msg5783 Author: [hidden] (ThomasAH) Date: 2016-07-08 07:16
* John Rouillard <issues@roundup-tracker.org> [20160707 14:01]:
> Also the user has the option of specifying the email address they want
> the recovery password sent to. If they specified an email address,
> should we mask it?

Yes, unless implementing the check is trivial.

> Should we return an error if the user supplies an invalid lookup email
> address rather than a username? I think my answer is no don't return
> an error but...
> 
> However we probably should always provide a positive response even if
> the username they asked for is invalid. Asking for a reset for the

I agree!

> user "donny" who doesn't exist should result in:
> 
>    Email has been sent to d**ny@rx*****.**m
> 
> The domain part of the result can be made up from random words/chars.

But it has to stay the same for every time a potential attacker asks
for the same username again, otherwise he could just ask twice and
see if the result changes.

But if we want to do this, the made-up domain part would have to be
the most commonly used domain in the tracker, otherwise it would be
easy to verify the existence of many accounts if a tracker has e.g.
70% users in domain "intevation.de" and we always send "m" at the
end:

donny -> d....@............m  (probably does not exist)
thomas -> t.....@............e (confirmed to exist)

Sounds a bit complicated?
Then maybe it is a bad idea to send obfuscated addresses?
Not sure.

> >This sometimes is really annoying, so I would prefer to only have this
> >as an option (if at all), not the default, as the default behavior of
> >roundup is a public tracker, even if we mostly use non-public trackers.
> 
> Agreed, it will be an tracker option maybe:
> 
>      mask_recovery_email = yes/no

I'd rather want three settings:
    foo_bar_option_name = show/hide/mask

> or even:
> 
>      recovery_email_mask_character = *
>
> default not set and no masking happens. If set to a character, masking
> happens using that character.

I don't think configuring the mask character is needed :)
And (ab)using such a setting for disabling/enabling the feature is
confusing.

> >To make the obfuscation yield more privacy, I suggest obfuscating more,
> >especially in the username part, as this often includes the real name of
> >people.
> >
> >What about replacing everything with dots, except for the first
> >character of the localpart, the @ and the last character of the domain
> >(and the dots :)), e.g.:
> >
> >user@example.com -> u...@..........m
> >user@example.net -> u...@..........t
> >firstname@example.com -> f........@..........m ->
> >firstname.lastname@ntvtn.de -> f.................@.......e
> 
> I am worried that that is too little info. I was trying to find a mask
> that displays places where there is likely to be a lot of variation in
> the unmasked bits. But still making enough to prevent somebody who
> won't know the original input from making an email address from
> it. Hence trying to include a couple of bytes of info around both
> sides of the @ sign.
> 
> I think if we can get a mask that allows for 5-10 plausible variations
> in email addresses we have done our job.
> 
> If it's a targeted attack against a specific user where the attacker
> has a lot of background knowledge, anything that would be useful to
> the actual account owner will also be useful to the attacker so...
> 
> Also I think losing the structure of the email address (i.e. what is a
> . in the address vs. what is a masking dot) is a problem as well, but
> setting a different "masking_character" config option allows the
> tracker admin to choose.
> 
> Maybe
> 
>   user@example.com -> u.er@ex........m
>   user@example.net -> u.er@ex........t
>   firstname@example.com -> f......me@ex........m ->
>   firstname.lastname@ntvtn.de -> f...............me@nt.....e
> 
> I have the same username at most places. The start of the domain spec
> is where the high entropy bits are located for my addresses.

Then it is even more important to mask more of the domain part, here
are two of your real addresses and five (probably) fictional addresses:

r...lj@us.........t
r...lj@cs.......u
r...lj@gm......m
r...lj@go...........m
r...lj@ho........m
r...lj@ms....m
r...lj@gm...e  (this one is a bit tricky for people outside Germany,
                but it is quite common here, maybe you know it)

You can clearly distinguish the first two real addresses.
Can you guess what the other five addresses are?
Could you still guess them with more masking?

r.....@........m
r.....@.............m
r.....@..........m
r.....@......m
r.....@.....e

But if you know that you have addresses at gmail.com,
googlemail.com, hotmail.com, msn.com and gmx.de, you can still
distinguish them. Not at a glance, but if you really need to know,
you can count the dots (or stars) and compare them to your addresses.
msg6005 Author: [hidden] (rouilj) Date: 2017-08-26 23:59
I am working on a simple change that I think handles the worst part of
this issue.

There are two code paths though the PasswordResetAction.

Path one is triggered if the URL invoking the password reset includes
a matching one time key (OTK). If the OTK matches an outstanding
password reset request, the password reset email is sent to the user
at their preferred address. The preferred address is the address that
received the email with the OTK. So displaying the email address here
doesn't matter as the viewer already knows about this address.

Path two is triggered by starting the password reset by entering a
username or any email associated with the account (either the primary
email or any alternate email).

If the user triggered the reset using the account name, displaying the
email is not desired. So I have changed the displayed message to:

  Email sent to primary notification address for <account name>.

If the user triggered a password reset using an associated email
address, showing the email address probably doesn't matter as the user
entered an address that matches a user. In this case I display:

  Email sent to <email address that was entered>.

Note that the existence of a username is kind of obvious since it is
displayed in every place where there is a link to the user. This change
just stops the email address from being exposed.

If the schema access rights are set to hide all of the usernames the
reset mechanism allows probing for usernames and email addresses. If
the probe guesses wrong, an error is raised rather than an "email has
been sent" message.

In this case I would suggest disabling the reset mechanism entirely
(although I am not quite sure how this would be done). Alternatively
implement a captcha, limit reset attempts or use another mechanism
to prevent trying to brute force accounts. See issue2550949 for ideas.

-- rouilj
msg6006 Author: [hidden] (rouilj) Date: 2017-08-27 00:58
Checked in in changeset: 3639f4b55936
msg6949 Author: [hidden] (rouilj) Date: 2020-08-29 04:27
> If the probe guesses wrong, an error is raised rather than
> an "email has been sent" message.
>
> In this case I would suggest disabling the reset mechanism
> entirely (although I am not quite sure how this would be done).

To do this just replace the passrst action using an extension.

The extension wraps the existing actions.PassResetAction to see if
the user email exists. If not return a "Email sent to $address"
using the submitted address but don't actually send anything. If
the email is valid call actions.PassResetAction to do the reset.

See how the login action is wrapped in: https://wiki.roundup-
tracker.org/LoginWithEmail

Added documentation on how password reset works in the web interface
rev:6257:f9c059921ccc
History
Date User Action Args
2020-08-29 04:27:56rouiljsetstatus: pending -> fixed
messages: + msg6949
2017-08-27 00:58:45rouiljsetstatus: open -> pending
resolution: fixed
messages: + msg6006
2017-08-26 23:59:57rouiljsetstatus: new -> open
assignee: rouilj
messages: + msg6005
2016-07-08 07:16:46ThomasAHsetmessages: + msg5783
2016-07-08 06:38:15bersetmessages: + msg5781
2016-07-07 12:01:49rouiljsetmessages: + msg5775
2016-07-07 09:17:07ThomasAHsetmessages: + msg5774
2016-07-05 23:58:04rouiljsetnosy: + rouilj
messages: + msg5760
2012-12-18 14:42:44ThomasAHsetnosy: + ThomasAH
messages: + msg4703
severity: minor -> normal
type: rfe -> security
2012-05-22 08:12:18bersetpriority: normal
2012-05-22 07:53:05bersetmessages: + msg4568
2012-05-22 00:35:54ezio.melottisetnosy: + ezio.melotti
messages: + msg4564
2011-08-11 10:54:34bersetnosy: + ber
messages: + msg4367
2011-08-05 10:00:33lukecreate