Joystream / Joystream/audits

Members can undermine the intent of the `invite_member` extrinsic by inviting themselves to get free tokens

Open
#3 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

S1 - low
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(
                &params.controller_account,
                default_invitation_balance
            );

            // Lock invitation balance. Allow only transaction payments.
            T::InvitedMemberStakingHandler::lock_with_reasons(
                &params.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:

  1. An attacker could use all their invites on themselves. That is, they could call invite_member and with params.controller_account == origin, for instance.
  2. 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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.