Member invitation by email address is vulnerable and allows user impersonation. When project admin invites a new member via email then Gitlab code match it with unverified email of different account. This gives an opportunity to an attacker to add legitimate member email address to his account and gain access to the private project.
Attack Scenario
Suppose there is company name xyz.org, all projects of this company are only accessible to its employees, that is those Gitlab accounts that have email addresses that match <employee_name>[@]xyz.org.
Attacker can add email address john@xyz.org to his personal Gitlab account which is an unverified email address and then all invitation to the john@xyz.org are actually goes to the attacker and he gains access to the private projects of the company.
PoC
Attacker account
Attacker has a verified primary email address which he owns
He adds another email address of the company employee john@gitlab-bounty.com in his account .
This will be an unverified secondary email address
Victim account
Creates a project named Gitlab-Bounty
Invites member to the project by email address john@gitlab-bounty.com
Bug
Gitlab will not check whether email address is verified or not and incorrectly matches the invitation to the attacker account.
Attacker successfully managed to impersonate a legitimate employee of the company and gain access to the private project and repository
Output of checks
This bug happens on GitLab.com. Probably instance too (please check)
Impact
Gitlab don't check verified email address prior to matching them with Gitlab accounts and this allows an attacker to gain access to private projects with higher permissions and impersonate legitimate members of the project.
Thank you for your submission. I hope you are well. Your report is currently being reviewed and the HackerOne triage team will get back to you once there is additional information to share.
Thanks for your report! I'm having some problems reproducing the issue you've reported:
Can you confirm the endpoint where the attacker should add the unverified email is the /-/profile/emails one?
Should the unverified email be a new one that hasn't been claimed by any other user?
I'm asking the 2nd question in particular since, from what's my understanding, the victim's unverified email should be added when a john@gitlab-bounty.com user is already registered on the same organization, so that the attacker will be able to get the victim's projects access.
However, while trying to add the unverified email of the already-registered user, I'm getting the following error:
- Email has already been taken
This makes impossible for the attacker to add the unverified email and therefore access the victim's project. I'm sure I'm missing something, could you kindly provide more information in order to make easier the reproduction of the issue?
Can you confirm the endpoint where the attacker should add the unverified email is the /-/profile/emails one?
Should the unverified email be a new one that hasn't been claimed by any other user?
Yes, the endpoint is /-/profile/emails and yes the unverified email is a new one that hasn't been claimed by any other user.
I'm asking the 2nd question in particular since, from what's my understanding, the victim's unverified email should be added when a john@gitlab-bounty.com user is already registered on the same organization, so that the attacker will be able to get the victim's projects access.
The attack scenario is not this but different based on the usage of member invitation. You see, if victim user is already registered on Gitlab then email invitation is not needed and when you invites someone via email then Gitlab automatically turns it into username invitation/addition.
The attack scenario I've describe is for the situation when a new employee who is not yet created his Gitlab account gets invited via email by the project admin. The employee then received invitation mail which contains a url to accepts and creates a new account on Gitlab.
I hope it clears the confusion. If not, then please let me know if you need any more info.
Thank you for your submission! We were able to validate your report, and have submitted it to the appropriate remediation team for review. They will let us know the final ruling on this report, and when/if a fix will be implemented. Please note that the status and severity are subject to change.
Say, there is a Super Secret Company that has a private super-secret-project on gitlab.com and one of the project users wants to invite one of their colleagues to the project for collaboration. They go to Project Members > Invite Members and can invite their colleagues using their email address, user@supersecret.com. Now if attacker knows this email address and knows that this email address has not been registered before on gitlab.com, the attacker can go to /profile/emails section on their account and add this victim's email address, user@supersecret.com, as one of their emails. Even if this email address is unverified, when the super-secret-project members go to Invite Members page and invite user@supersecret.com, the attacker account ends up getting access to the super-secret-project. We are not validating if a user has verified the email addresses they added to their account before giving their account access to groups/projects when one of those unverified email addresses is used for an invite.
This issue has similarities with #336169 (closed) and that issue has lower severity because we are assuming the project Maintainer is malicious there. In this issue, there is no malicious intent on the project members/maintainer side and unbeknownst to them, they end up inviting random users to their private project through this bug.
Hope this made sense and let me know if you have any questions? Thank you.
The solution here could be do not use unverified email addresses?
@mksionek Yep, check to make sure if the email address associated with an account is verified before giving access to the account that email address is tied to. Also, how do we handle a scenario where 2 or more accounts have the same email address (as secondary email) for which an invite was sent? Which account(s) would end up getting access? Should we just restrict this feature to primary email?
I actually think impersonation is ~"group::authentication and authorization" .
@ogolowinski The attacker or any other user in the exploit is not impersonating anyone, like in the admin sense, if you mean that. Sorry, if that term is misleading. This issue is similar to #336169 (closed) in the sense that it is exploiting a bug in invite a user by email feature. I'm updating the issue title to reflect this.
@ogolowinski I think what it boils down to is "who owns the invite user by e-mail feature". I think this would fall under user management and therefore ~"group::authentication and authorization".
Rohit Shambhunichanged title from Ability to gain access to private project with higher permission access by impersonating other legitimate members of the project to Ability to gain access to private project through an email invite by using other user's email address as a secondary email
changed title from Ability to gain access to private project with higher permission access by impersonating other legitimate members of the project to Ability to gain access to private project through an email invite by using other user's email address as a secondary email
Based on the description above it seems the fix should be as simple as using only verified email (at least the first iteration as a security fix). @bdenkovych could you please estimate weight here?
Thanks for working on this @(confidential)! We've removed the Seeking community contributions label to avoid having multiple people working on the same issue.
Bogdan Denkovychchanged title from Ability to gain access to private project through an email invite by using other user's email address as a secondary email to Ability to gain access to private project through an email invite by using other user's email address as an unverified secondary email
changed title from Ability to gain access to private project through an email invite by using other user's email address as a secondary email to Ability to gain access to private project through an email invite by using other user's email address as an unverified secondary email
This issue is just one of the side effects of a bigger issue - GitLab links unverified secondary emails to users.
It is right to link unverified primary emails to users since GitLab creates an account for those emails during sign up and doesn't allow to change it later to another email without verification. It is not a case for secondary emails.
Users could add lots of unverified secondary emails and as you see it leads to security and typebug issues.
About this issue: When inviting a new member to a group|project via UI or API by email that belongs to some user as an unverified secondary email, it invites that user to that group|project. We should send an invite to that email instead. There are lots of other issues where linking unverified secondary emails to users causes issues, like with push rules, code owners, commit's authors, etc. Here is MR with bunch of tests that highlight those issues and eliminate them: https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/2491/.
That fix should be enough to fix this security issue.
I predict another typebug issues that are caused by GitLab links unverified secondary emails to users.
That can be fixed on the public repo. Currently, GitLab also reserves unverified secondary emails, so it is not possible to create a new account or add such emails as secondary to other users. It leads to lots of bugs. GitLab should not reserve unverified secondary emails till they are confirmed.
Examples:
A malicious user could add emails of potential customer (admin|john|etc)@xyz.org as secondary unverified emails. When such customer decides to start using GitLab.com, they will not be able to create an account for their employees.
And bug related to this issue directly: To accept an invite that is sent to emails, which are unverified secondary emails of some users, it is needed to create a GitLab account with this email or add it to an existing account as a secondary verified email. Currently, it is not possible to do so.
Please let me know what you think about this direction? I don't see any other alternative solutions to it yet.
So, if I understand the fix correctly we are letting a user be added to a project, apply push rules (based on their supposed email address) etc. only if their email is confirmed, be it primary or secondary? Is my understanding right?
If yes, how do we deal with the scenario I mentioned above, quoted below?
Also, how do we handle a scenario where 2 or more accounts have the same email address (as secondary email) for which an invite was sent? Which account(s) would end up getting access? Should we just restrict this feature to primary email?
Regarding the following comment you had above:
We should send an invite to that email instead.
The email invitation based workflow seems like an alternative solution to what you are proposing above. ~"group::workspace" is planning on working on a invitation based feature this year. See https://gitlab.com/groups/gitlab-org/-/epics/4974+. This feature would also address a few other security issues mentioned here.
Do you see the email based invitation workflow as a part of the solution in addressing this issue? As far as I understand, if we are verifying if a user's email is verified before making any actions on their account based on that email address, we should be ok from a security perspective right? We don't need the email invitation based workflow feature in that case right? Let me know if you disagree?
So, if I understand the fix correctly we are letting a user be added to a project, apply push rules (based on their supposed email address) etc. only if their email is confirmed, be it primary or secondary? Is my understanding right?
That is right only for secondary emails, but not primary emails. As I mentioned in the first message:
It is right to link unverified primary emails to users since GitLab creates an account for those emails during sign-up and doesn't allow to change it later to another email without verification. It is not a case for secondary emails.
GitLab creates an account for an email specified during the sign-up and this email is the primary email. We cannot defend ourselves from malicious sign-ups. But they won't be able to do anything with the account since they have no access to the email to confirm that, so the owner of that email is able to remove this created account or report it or something.
Also, how do we handle a scenario where 2 or more accounts have the same email address (as secondary email) for which an invite was sent? Which account(s) would end up getting access? Should we just restrict this feature to primary email?
That is the point - not assume that secondary email belongs to users till it is verified. Of course, GitLab should prevent adding or verifying emails, which are already someone's verified secondary email or verified/unverified primary email, to another user.
Which account(s) would end up getting access?
The account which verifies this email first, would get the access - it could be either via sign up and verify flow or adding secondary email to account and verify flow.
Should we just restrict this feature to primary email?
We do not send invites to primary emails we just link them to existing users, add them to members, and send the message to inform them they were invited. I don't like this solution because is a breaking change, it would increase complexity, and because this fixes only one issue we know.
Do you see the email based invitation workflow as a part of the solution in addressing this issue?
I think it is a great feature and it partially fixes the current issue. But it is not a reliable solution to fix the current issue. Example: When you type emails that are unverified secondary emails of some users, GitLab UI would still substitute those emails to those users and send the invite to primary emails of that user. That is just one small issue among others that comes from GitLab links unverified secondary emails to users.
And bug related to this issue directly: To accept an invite that is sent to emails, which are unverified secondary emails of some users, it is needed to create a GitLab account with this email or add it to an existing account as a secondary verified email. Currently, it is not possible to do so.
I want to clarify the mentioned above bug. It doesn't mean that the suggested solution would introduce this typebug. It will just allow reproducing this bug in additional way. Currently, this bug can be reproduced in the following way:
Invite a new member to project|group by email that is not related to any user account.
Invite got to the inbox of the owner of the email.
Somebody adds this email to their account as an unverified secondary email.
The owner of the email tries to accept the invite(aka either create new account with this email and verify the email or add this email existing account as secondary and verify it).
it seems the fix should be as simple as using only verified email
We cannot just allow invites to be sent to verified emails only, or primary emails only, or something. It would be a breaking change. Some customers might have automation that invites new team members to their group by sending their emails to API endpoint that creates an invite, or something.
Also, we cannot just prevent sending invites to unverified secondary emails, because it would lead to inconsistency and won't fix the root cause that leads to lots of other similar issues I mentioned before.
The solution I mentioned #356665 (comment 1000391775), feels consistent, complete, and should eliminate all those sides effects.
One of the issues Support has right now is that we see unverified secondary email addresses preventing users from creating a new account and the only way to deal with this is to have an admin manually remove it.
Thanks for the clarification @bdenkovych! Solution LGTM. No further comments from me.
I predict another typebug issues that are caused by GitLab links unverified secondary emails to users. That can be fixed on the public repo. Currently, GitLab also reserves unverified secondary emails, so it is not possible to create a new account or add such emails as secondary to other users. It leads to lots of bugs. GitLab should not reserve unverified secondary emails till they are confirmed.
Also to fixing this typebug on canonical after the security fix for this issue goes out.
When this fix is released and this issue becomes publicly available, I'll create a new issue and describe in detail the typebug based on this discussion. I added it to my To-Do list.
I created the follow-up issue to fix the mentioned bug. Currently, I marked it as confidential to not reveal details of this security issue. #367823 (closed)