diff --git a/src/Simplex/Chat/Library/Commands.hs b/src/Simplex/Chat/Library/Commands.hs index a132074d76..9de7d44a2b 100644 --- a/src/Simplex/Chat/Library/Commands.hs +++ b/src/Simplex/Chat/Library/Commands.hs @@ -3899,6 +3899,10 @@ processChatCommand vr nm = \case let FixedLinkData {linkConnReq = cReq, linkEntityId} = fd linkInfo = GroupShortLinkInfo {direct, groupRelays = relays, sharedGroupId = B64UrlByteString <$> linkEntityId} groupSLinkData_ <- liftIO $ decodeLinkUserData cData + -- Validate link entity ID matches group profile's sharedGroupId + forM_ groupSLinkData_ $ \GroupShortLinkData {groupProfile = GroupProfile {sharedGroupId}} -> + unless ((B64UrlByteString <$> linkEntityId) == sharedGroupId) $ + throwChatError CEInvalidConnReq plan <- groupJoinRequestPlan user cReq (Just linkInfo) groupSLinkData_ pure (con cReq, plan) where diff --git a/src/Simplex/Chat/Library/Subscriber.hs b/src/Simplex/Chat/Library/Subscriber.hs index 24a35d034b..6083057b57 100644 --- a/src/Simplex/Chat/Library/Subscriber.hs +++ b/src/Simplex/Chat/Library/Subscriber.hs @@ -746,8 +746,10 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = _ -> messageError "CONF from invited member must have x.grp.acpt" GCHostMember -> case chatMsgEvent of - XGrpLinkInv glInv -> do + XGrpLinkInv glInv@GroupLinkInvitation {groupProfile = GroupProfile {sharedGroupId = rcvGId}} -> do -- XGrpLinkInv here means we are connecting via prepared group, and we have to update user and host member records + let GroupInfo {groupProfile = GroupProfile {sharedGroupId = curGId}} = gInfo + when (rcvGId /= curGId) $ messageError "x.grp.link.inv: sharedGroupId mismatch" (gInfo', m') <- withStore $ \db -> updatePreparedUserAndHostMembersInvited db vr user gInfo m glInv -- [incognito] send saved profile incognitoProfile <- forM customUserProfileId $ \pId -> withStore (\db -> getProfileById db userId pId) @@ -3611,7 +3613,9 @@ runRelayRequestWorker a Worker {doWork} = do (FixedLinkData {linkEntityId, rootKey}, cData@(ContactLinkData _ UserContactData {owners})) <- getShortLinkConnReq NRMBackground user reqGroupLink liftIO (decodeLinkUserData cData) >>= \case Nothing -> throwChatError $ CEException "getLinkDataCreateRelayLink: no group link data" - Just GroupShortLinkData {groupProfile = gp} -> do + Just GroupShortLinkData {groupProfile = gp@GroupProfile {sharedGroupId}} -> do + unless ((B64UrlByteString <$> linkEntityId) == sharedGroupId) $ + throwChatError $ CEException "getLinkDataCreateRelayLink: linkEntityId does not match profile sharedGroupId" validateGroupProfile gp gVar <- asks random (_, memberPrivKey) <- liftIO $ atomically $ C.generateKeyPair gVar