GetRankInGroup and GetRoleInGroup should not cache

As a Roblox developer, it is currently too hard to get up to date group rank/role information from the server without relying on the client (which can be exploited to give wrong information back to the server).

Right now, if I want to get current group role or rank information, I have to invoke a RemoteFunction and have the client call the functions, like below:

Code Snippet (Not Protected)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GetPlayerRank = ReplicatedStorage:WaitForChild("GetPlayerRank")
local player = game.Players.LocalPlayer

GetPlayerRank.OnClientInvoke = function(group, role)
	if role then
		return player:GetRoleInGroup(group)
	else
		return player:GetRankInGroup(group)
	end
end

This is problematic because if the client changes their UserId, it’ll get group information based on the UserId instead of the player’s own UserId. This requires developers to also pass the player’s UserId when invoking the RemoteFunction, just to make sure the client is using the right one.

Code Snippet (Protected)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GetPlayerRank = ReplicatedStorage:WaitForChild("GetPlayerRank")
local player = game.Players.LocalPlayer

GetPlayerRank.OnClientInvoke = function(userId, group, role)
	if player.UserId ~= userId then
		player:Kick("Your ID did not match!")
		if role then
			return "Guest"
		else
			return 0
		end
	end
	if role then
		return player:GetRoleInGroup(group)
	else
		return player:GetRankInGroup(group)
	end
end

Ideally, this should be changed to one of the following:

  1. Calling either of the functions from the server should give up to date information on a player’s group role or rank. Developers shouldn’t have to create a RemoteFunction to get the information from the client.
  2. The UserId property of Player should be read-only, as there is no reason for it to change. At the very least, it won’t be easy enough for exploiters to just run a single localscript to change their UserId.

Optionally also update the wiki for GetRankInGroup and GetRoleInGroup to let users know that obtaining group information from the client may be inaccurate.

15 Likes

This is what GroupService is for. The issue, in my opinion, is that these two methods aren’t deprecated which can lead someone to believe they’re the only option.

Though GroupService has no methods to directly obtain ranks or roles of users, there are ways to check, which are maybe more work than they should be. For that reason, I made a simple module to save the little amount of time it takes to make your own functions.

At this point in time, having group-related functions under the player object instead of in GroupService seems terribly disorganized, so I believe there really should be no more focus on these functions.

2 Likes