Open viniul opened 3 years ago
The issue could be exploited even with the "not a member controller account" check because of the controller account change mechanism. We are introducing the check for the existing invitation lock to allow doing the "trick" only once.
Thanks for pointing this out @shamil-gadelshin! Could you elaborate on the check you are introducing? Where and how exactly would this check be introduced?
Could you elaborate on the check you are introducing? Where and how exactly would this check be introduced?
There is a mistake in the invite_member
extrinsic. We didn't check for existing locks. It allowed inviting a member multiple times with printing money to the same account with no effective locks except the first one because locks were overlapping. The coming PR introduces such a check: https://github.com/Joystream/joystream/pull/2187
Summary
The
membership
pallet grants every user who bought a membership the possibility to invite a limited number of other members. Upon inviting otherAccountId
s, those account ids are granted an initialinvitation_balance
, which can only be used to pay Transaction fees. Right now, it is possible to transfer thisinvitation_balance
to one's own account, by inviting one's own account id. It is also possible to inviteAccountId
which already have a membership, which undermines the intent of the invitation system.To mitigate this issue, only allow invites to
controller_ids
which are not already tied to any membership.Issue Details
The
invite_member
extrinsicruntime-modules/membership/src/lib.rs
takes as an argument theInviteMembershipParameters
, which includes thecontroller_account
. In the extrinsic, an initialinvitation_balance
is transferred from the membership working group balance is to thecontroller_account
. Thisinvitation_balance
can only be used to pay transaction fees:The intent of this invitation balance is to draw more members towards the Joystream platform. However, the
invite_member
extrinsic allows members to invite a Member with acontroller_account
that actually already has a membership. Thiscontroller_account
would be granted theinitial_invitation
balance, undermining the intent of the extrinsic.In the current configuration, upon buying a membership, 5 invites are granted. Those 5 invites will add up to a total balance of
500
tokens being deposited.To mitigate this issue, only allow invites to
controller_ids
which are not already tied to any membership.Risk
This can be abused in two ways:
invite_member
and withparams.controller_account == origin
, for instance.initial_invitation_balance
Since invited members are not granted any further invites, this is issue is only low severity.
Mitigation
In the
invite_member
extrinsic, enforce that members can only invite accounts with acontroller_account
that does not control a membership yet. Another way would be to not pay any balance tocontroller_account
in case thecontroller_account
does already have existing membership.