What private server owners should be able to change
Private server commands that give coins, pets or levels let anyone with a server farm saved progress. How to keep owner commands to things that end with the server.
What it looks like
Private server owners get commands in their own server, and some of those commands give something that's saved: currency, items, levels, wins or leaderboard stats. Or the check for "this is a private server" lets in more people than the owner.
Luau
if player.UserId == game.PrivateServerOwnerId then profile.Coins += amount end
How to detect it
- Find every use of
game.PrivateServerOwnerIdandgame.PrivateServerId, and every command system with a "VIP server" or "private server" mode. - For each command those players get, ask whether its effect outlives the server. Anything written to a profile, data store, ordered data store or badge does.
- Look for indirect routes: a server-wide multiplier, event or drop-rate setting that a private server owner can switch on, and that boosts rewards which are then saved.
- Check how ownership is decided.
PrivateServerIdis also set in reserved servers made withReserveServerAsync, sogame.PrivateServerId ~= ""on its own gives the commands to everyone in every reserved server. UsePrivateServerOwnerId, which is0in standard and reserved servers.
What an exploiter could do
Private servers can be free, depending on the game's settings, and a paid one is open to anyone willing to pay. Anyone who owns one can farm currency, items or levels with no one to stop them, then take them into public servers, trade them where the game allows it, or climb the leaderboards.
How to fix it
- Keep private server commands to things that end with the server: time of day, gravity, music, picking the map, or kicking players from that server.
- If a command must touch progress, such as a practice mode, don't save what's earned there, or save it separately from the main profile.
- Decide ownership with
player.UserId == game.PrivateServerOwnerId, checked on the server.
Vulnerable example
Vulnerable
local Lighting = game:GetService("Lighting") local Players = game:GetService("Players") local PlayerData = require(script.Parent.PlayerData) local function onChatted(player: Player, message: string) if game.PrivateServerOwnerId == 0 or player.UserId ~= game.PrivateServerOwnerId then return end if message == ";night" then Lighting.ClockTime = 0 elseif message == ";coins" then local profile = PlayerData.get(player) if profile then profile.Coins += 1000 end end end Players.PlayerAdded:Connect(function(player) player.Chatted:Connect(function(message) onChatted(player, message) end) end)
Fixed example
Fixed
local Lighting = game:GetService("Lighting") local Players = game:GetService("Players") local function onChatted(player: Player, message: string) if game.PrivateServerOwnerId == 0 or player.UserId ~= game.PrivateServerOwnerId then return end if message == ";night" then Lighting.ClockTime = 0 elseif message == ";day" then Lighting.ClockTime = 12 end end Players.PlayerAdded:Connect(function(player) player.Chatted:Connect(function(message) onChatted(player, message) end) end)
Common false positives
- Commands that only change the server itself, like lighting, music or which map loads next, are fine for private server owners.
- Kicking players from the owner's own server is normal. Banning them from the whole game is not.
- Games that turn saving off in private servers, or save private server progress separately, can give owners anything. Check that the save code really does skip it.