You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
if(invitation.user)throwAPI_ERROR('REGISTRATION_ERROR','Invitation is invalid.');// ^^^^
The code attempts to validate if the invitation was already used by checking if the property invitation.user is true. However, when an invitation is used, it's the property invitation.used that is set to true (the last letter is a "d", not an "r").
Despite the invitation being marked as used when somebody uses it to register, this property is never actually checked. invitation.user will always return false since this property does not exist, and invitations will never be considered to be invalid.
Exploitation
Steps to reproduce:
Go to https://effectindex.com/admin/users/invite and generate an invitation.
Use the invitation to register a new user called urmom.
Use the same invitation again to register a new user called urdad. It works.
Use the same invitation again to register a new user called urstepsis. It works again.
An attacker could monitor the Discord server for the invitation codes that Josie sometimes posts publicly, and they could easily reuse those codes to register new accounts.
Second bug: invitation codes are NOT random and they can be easily guessed
Description
You might think about the first bug: that's no big deal, we will just tell Josie to stop posting invitations in Discord and only send them privately. But that does not change anything because the invitation codes can actually easily be guessed.
Go to https://effectindex.com/admin/users/invitations again to generate an invitation. In my case, the invite code was 63447a2d35688befb5e88246. 63447a2d is the timestamp, 35688b is the machine ID, efb5 is the process ID, and e88246 is an incremental ID.
Register a new user with this invite.
Do some other random stuff on the website, whatever,. For instance, post a new trip report.
Query the public API https://effectindex.com/api/reports and take note of the most recent ObjectId (i.e. sort them alphabetically and take the last one). In my case it was 634480d735688befb5e882be. 634480d7 is the timestamp (notice how it is close to 63447a2d?), 35688b is the machine ID (the same value as before), efb5 is the process ID (same again), and e882be is an incremental ID (notice how it is close to e88246?)
Put the trip report ID in the tool mongo-objectid-predict and it will generate a list of predicted ObjectIds
Use a script or a fuzzing tool like Burp Intruder or wfuzz to attempt to register a user using all these predicted codes until it works.
Therefore, an attacker could monitor the Discord server, waiting for someone to request an invite. When the attacker sees that Josie or another admin answered "ok I just sent you an invite code privately", the attacker knows the approximate timestamp of the invitation (the first 8 hex digits). Since the precision of the timestamp is in seconds, it's easy to bruteforce all timestamps for the last few minutes.
The attacker could then scrape the website to search for the most recent ObjectId in order to obtain the machine ID, the process ID (assuming the server did not restart), and an incremental ID that is presumably close to the one of the invite. The attacker can then easily bruteforce the invitation code.
If you're still not convinced, I can show you a real life example in prod. One of the invite codes that Josie sent on Discord was 5c6df23c6be7df2fcba1930c. If you go to https://effectindex.com/api/profiles/user/Rho, you can see that their ObjectID is 5c6e13166be7df2fcba1930e. This would definitely have been found by the tool mongo-objectid-predict
The attacker could even automate this process in order to race the legitimate user and register before them. Therefore, even if the first bug is fixed, this one is still exploitable.
The text was updated successfully, but these errors were encountered:
First bug: invitations can be reused infinitely due to a typo in the source code
I've noticed this already, I've been diligent with deleting invites as soon as they're used and only sending them out in dms.
An attacker could monitor the Discord server for the invitation codes that Josie sometimes posts publicly, and they could easily reuse those codes to register new accounts.
This hasn't been done since 2019, back when Viscid ran the project. Though, that said, it would be good to fix this (and these days, the project is much too big to just post invites out like that).
Thank you for the very through security report, even though this one isn't actively exploitable (no active invites + the machine ID and process ID should have changed by now), I'd prefer you report them to one of the staff on the discord or email us.
I would like to report two security bugs. The two bugs can be combined in order to register on the website without being authorized.
First bug: invitations can be reused infinitely due to a typo in the source code
Description
In /server/models/users/index.js#L59, there is a typo:
The code attempts to validate if the invitation was already used by checking if the property
invitation.user
istrue
. However, when an invitation is used, it's the propertyinvitation.used
that is set to true (the last letter is a "d", not an "r").Despite the invitation being marked as
used
when somebody uses it to register, this property is never actually checked.invitation.user
will always returnfalse
since this property does not exist, and invitations will never be considered to be invalid.Exploitation
Steps to reproduce:
https://effectindex.com/admin/users/invite
and generate an invitation.urmom
.urdad
. It works.urstepsis
. It works again.An attacker could monitor the Discord server for the invitation codes that Josie sometimes posts publicly, and they could easily reuse those codes to register new accounts.
Second bug: invitation codes are NOT random and they can be easily guessed
Description
You might think about the first bug: that's no big deal, we will just tell Josie to stop posting invitations in Discord and only send them privately. But that does not change anything because the invitation codes can actually easily be guessed.
Indeed, MongoDB ObjectIds are used directly as invitation codes, as seen in /server/models/invitations/index.js#L27.
This has been well documented multiple times: these IDs are not random at all:
There is even a tool that helps attacker predicting ObjectIds from a known one: https://github.com/andresriancho/mongo-objectid-predict.
Exploitation
Steps to reproduce:
https://effectindex.com/admin/users/invitations
again to generate an invitation. In my case, the invite code was63447a2d35688befb5e88246
.63447a2d
is the timestamp,35688b
is the machine ID,efb5
is the process ID, ande88246
is an incremental ID.https://effectindex.com/api/reports
and take note of the most recent ObjectId (i.e. sort them alphabetically and take the last one). In my case it was634480d735688befb5e882be
.634480d7
is the timestamp (notice how it is close to63447a2d
?),35688b
is the machine ID (the same value as before),efb5
is the process ID (same again), ande882be
is an incremental ID (notice how it is close toe88246
?)mongo-objectid-predict
and it will generate a list of predicted ObjectIdsTherefore, an attacker could monitor the Discord server, waiting for someone to request an invite. When the attacker sees that Josie or another admin answered "ok I just sent you an invite code privately", the attacker knows the approximate timestamp of the invitation (the first 8 hex digits). Since the precision of the timestamp is in seconds, it's easy to bruteforce all timestamps for the last few minutes.
The attacker could then scrape the website to search for the most recent ObjectId in order to obtain the machine ID, the process ID (assuming the server did not restart), and an incremental ID that is presumably close to the one of the invite. The attacker can then easily bruteforce the invitation code.
If you're still not convinced, I can show you a real life example in prod. One of the invite codes that Josie sent on Discord was
5c6df23c6be7df2fcba1930c
. If you go tohttps://effectindex.com/api/profiles/user/Rho
, you can see that their ObjectID is5c6e13166be7df2fcba1930e
. This would definitely have been found by the toolmongo-objectid-predict
The attacker could even automate this process in order to race the legitimate user and register before them. Therefore, even if the first bug is fixed, this one is still exploitable.
The text was updated successfully, but these errors were encountered: