fix: don't check permissions if revealed accounts aren't legit

This seems to be a bug that was introduced when two features, admin
permissions and "always reveal wallet accounts" where merged.

We need to make sure we **first** check the revealed accounts and only
**then** do we perform permission checks on them. Otherwise we can run
into scenarios where fake addresses are used and users will be accepted
to the community.
This commit is contained in:
Pascal Precht 2023-06-19 12:33:48 +02:00 committed by Follow the white rabbit
parent a36202ff30
commit f702b54d08
1 changed files with 32 additions and 32 deletions

View File

@ -1783,6 +1783,38 @@ func (m *Manager) HandleCommunityRequestToJoin(signer *ecdsa.PublicKey, request
return nil, err
}
if len(request.RevealedAccounts) > 0 {
// verify if revealed addresses indeed belong to requester
for _, revealedAccount := range request.RevealedAccounts {
recoverParams := account.RecoverParams{
Message: types.EncodeHex(crypto.Keccak256(crypto.CompressPubkey(signer), community.ID(), requestToJoin.ID)),
Signature: types.EncodeHex(revealedAccount.Signature),
}
recovered, err := m.accountsManager.Recover(recoverParams)
if err != nil {
return nil, err
}
if recovered.Hex() != revealedAccount.Address {
// if ownership of only one wallet address cannot be verified,
// we mark the request as cancelled and stop
err = m.markRequestToJoinAsCanceled(signer, community)
if err != nil {
return nil, err
}
requestToJoin.State = RequestToJoinStateDeclined
return requestToJoin, nil
}
}
// Save revealed addresses + signatures so they can later be added
// to the community member list when the request is accepted
err = m.persistence.SaveRequestToJoinRevealedAddresses(requestToJoin)
if err != nil {
return nil, err
}
}
becomeAdminPermissions := community.TokenPermissionsByType(protobuf.CommunityTokenPermission_BECOME_ADMIN)
becomeMemberPermissions := community.TokenPermissionsByType(protobuf.CommunityTokenPermission_BECOME_MEMBER)
@ -1847,38 +1879,6 @@ func (m *Manager) HandleCommunityRequestToJoin(signer *ecdsa.PublicKey, request
requestToJoin.State = RequestToJoinStateAccepted
}
// Save revealed addresses + signatures so they can later be added
// to the community member list when the request is accepted
if len(request.RevealedAccounts) > 0 {
// verify if revealed addresses indeed belong to requester
for _, revealedAccount := range request.RevealedAccounts {
recoverParams := account.RecoverParams{
Message: types.EncodeHex(crypto.Keccak256(crypto.CompressPubkey(signer), community.ID(), requestToJoin.ID)),
Signature: types.EncodeHex(revealedAccount.Signature),
}
recovered, err := m.accountsManager.Recover(recoverParams)
if err != nil {
return nil, err
}
if recovered.Hex() != revealedAccount.Address {
// if ownership of only one wallet address cannot be verified,
// we mark the request as cancelled and stop
err = m.markRequestToJoinAsCanceled(signer, community)
if err != nil {
return nil, err
}
requestToJoin.State = RequestToJoinStateDeclined
return requestToJoin, nil
}
}
err = m.persistence.SaveRequestToJoinRevealedAddresses(requestToJoin)
if err != nil {
return nil, err
}
}
return requestToJoin, nil
}