Help needed with securing admin panel code

This is probably not the right place to post it, tell me where to on the comments.

So, I have started working on a admin panel today and managed to add some good features. But, I saw my code was not server-side which I think makes it less secure, so I put it on ServerScriptService and made it server-side, but I decided to use RemoteServers, but I am worried that someone may use RemoteSpy or something to fire my remotes. What is the best way to secure admin code?

Here is the server-side code using RemoteFunction:

local function onSetJumpPower(player, power)
	player.Character.Humanoid.JumpPower = power
end

local setJumpPower = game.ReplicatedStorage.SetJumpPower

setJumpPower.OnServerInvoke = function(player, power)
	if player.Character then
		onSetJumpPower(player, power)
		return true
	else
		return false
	end
end

Here is the server-side code:

local function setJumpPower(player, power)
    player.Character.Humanoid.JumpPower = power
end

local button = script.Parent
local textBox = button:FindFirstChild("JumpPowerBox")

button.MouseButton1Click:Connect(function()
    local input = textBox.Text
    local power = tonumber(input)
    if power and power >= 0 then
        setJumpPower(game.Players.LocalPlayer, power)
    else
        print("Invalid input:", input)
        textBox.Text = "Invalid input"
    end
end)

So which is better? How can I secure main panel code? And, are there more secure ways? This is a important aspect, that if in the wrong hands, can be bad.

Check the player’s user id on the server. Exploiters can’t change their user id so you can secure it that way. You could also kick the player if they fire it and are not an admin, because that wouldn’t be possible without exploits.

Be careful with how much of your anti exploit code you share on forums, as exploiters may freely browse these topics. As @jogglejames mentioned, you should check every remote that is fired to see if the user has permission to carry out the command in question. This should be done for all remoteevents, the all remotes are just requests for the server, where the server should decide if it grants the request or not.

Also, the first alternative is way better than the second alternative. As you will require more processing power using the second alternative. A remote an exploiter can’t use doesn’t do any harm, which is the case when using a remote with userid check.

I do that, but I need help about the code.

What exactly do you need help with?

So, basically, I need help with where to put the code/tips for securing with doing the stuff only for admins.

I’d recommend having the GUI in serverstorage, and clone it into the correct players UI. Also utilize remote functions, just as you have, and check if the players have access to do what they request to do. If they don’t you might have found an exploiter :slight_smile:

basically save a table of Player Ids which are admins

AdminTable={
[123123123]=true,
[321321321]=true
}

and then add at the beginning of the script

if not AdminTable[Player.UserId] then
return
end

So basically, on the server script whenever the remote event is fired and an if statement and check if the player is an admin. Here’s and example:

local userId = --Your userId

game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(player)
    if player.UserId == userId then --Check if the player has permission
        --Do your stuff
    else
        player:Kick() --Kick the player if they are an exploiter
    end
end)

Thanks to everyone for their tips, will use!

Also, I made a user ID check, but I am scared about security, what should I do?

1 Like

Nothing, this check is enough, since exploiter cannot fake the player userid in server

An Exploiter can join your game with the mod/admin in the server. They can clone the mod/admin Gui to them. If this happen, sanity/security check need to be implemented on the server.

By default, RemoteEvent pass a player who fired it.
You can check the player id on the server. If it match the admin/mod id, proceed with the command.
Else, kick/warn the player instead.

I have added a user ID check, banning the user if they see the UI with invalid ID and it is server-side, I am thinking about adding something else like a secret word for admins.

1 Like

This is only needed if someone gains access to the admin account, but I think this is unlikely.

1 Like

I will also use RemoteFunctions/RemoteEvent and secure them by letting a user ID fire them (if possible)

1 Like

You need to check upon receipt

If it’s a chat command, you can split the message for example:

/kick player : secretcode
-- /kick, is  a command
-- player, the targeted player
-- secretcode, a int/string that needed to validate the command. NEED TO BE UNIQUE

You can achieve this by using string.sub,split and more.

Nice, also here is my code, let me know any tips (Kick messages and stuff is changed to avoid exploiters reading this)

local DataStoreService = game:GetService("DataStoreService")
local BanDataStore = DataStoreService:GetDataStore("BannedPlayers")
local Players = game:GetService("Players")
local StarterGui = game:GetService("StarterGui")
local Whitelist = {2899834302}


local adminFunction = Instance.new("RemoteFunction")
adminFunction.Name = "Test"
adminFunction.Parent = game:GetService("ReplicatedStorage")
adminFunction.OnServerInvoke = function(player)
	if table.find(Whitelist, player.UserId) then
		local admin = StarterGui.EliteAdminGui.EliteAdminButton
		admin.Visible = true
		admin.Active = true
		return true
	end
	return false
end

local function onPlayerAdded(player)
	local userId = player.UserId
	local admin = StarterGui.EliteAdminGui.EliteAdminButton

	
	if table.find(Whitelist, userId) then
		admin.Visible = true
		admin.Active = true
	else
		admin.Visible = false
		admin.Active = false

		
		if admin.Visible then
			local success, err = pcall(function()
				BanDataStore:SetAsync(tostring(userId), true)
			end)
			if not success then
				warn("Failed to ban player:", err)
			end
			player:Kick(".")
		end
	end
end

for _, player in ipairs(Players:GetPlayers()) do
	onPlayerAdded(player)
end

Players.PlayerAdded:Connect(onPlayerAdded)
1 Like

This won’t work, you need to change the value in the PlayerGui, not the StarterGui

local admin = StarterGui.EliteAdminGui.EliteAdminButton
local admin = player.PlayerGui:WaitForChild("EliteAdminGui").EliteAdminButton

And I recommend not to put your admin gui in the StarterGui, but put it in a script and when adding a player, copy it to his PlayerGui folder for safety