Open the-remmer opened 1 year ago
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.
That said, I'll be looking into fixing this ASAP.
See 1cfdfa4b51b6241f7cd817e6eb839de56b9a9b27 for a fix for 1.
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.