Members can undermine the intent of the `invite_member` extrinsic by inviting themselves to get free tokens
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 2
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
Summary
The membership pallet grants every user who bought a membership the possibility to invite a limited number of other members. Upon inviting other AccountIds, those account ids are granted an initial invitation_balance, which can only be used to pay Transaction fees. Right now, it is possible to transfer this invitation_balance to one's own account, by inviting one's own account id. It is also possible to invite AccountId 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 extrinsic runtime-modules/membership/src/lib.rs takes as an argument the InviteMembershipParameters, which includes the controller_account . In the extrinsic, an initial invitation_balance is transferred from the membership working group balance is to the controller_account. This invitation_balance can only be used to pay transaction fees:
pub fn invite_member(origin,
params: InviteMembershipParameters)
[...]
// Create default balance for the invited member.
let _ = balances::Module::::deposit_creating(
¶ms.controller_account,
default_invitation_balance
);
// Lock invitation balance. Allow only transaction payments.
T::InvitedMemberStakingHandler::lock_with_reasons(
¶ms.controller_account,
default_invitation_balance,
WithdrawReasons::except(WithdrawReason::TransactionPayment)
);
[...]
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 a controller_account that actually already has a membership. This controller_account would be granted the initial_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:
- An attacker could use all their invites on themselves. That is, they could call
invite_memberand withparams.controller_account == origin, for instance. - Two attackers who already have membership could invite each other and get granted 5*
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 a controller_account that does not control a membership yet. Another way would be to not pay any balance to controller_account in case the controller_account does already have existing membership.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in runtime-modules/membership/src/lib.rs at the invite_member extrinsic and its InviteMembershipParameters controller_account argument. Trace how existing memberships are identified, then verify that self-invites and controller accounts already tied to a membership are rejected without receiving invitation_balance.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100