How to stop hackers from firing remote events connected to local scripts?

No, you can’t. Exploiters can simply call :FireServer from their script executers, there’s no difference between a :FireServer call from a localscript and one from a script executer.

That’s what I just asked you.
“What I’m asking is, is there a way to tell who set off the remote no matter what they did to do it?”

Yes, I literally just told you so

You just said the same thing both way. Yes they can and no that can’t without a name being trapped.
if there is no way to set off a remote without the name being trapped you should be able to figure out they are hacking.

Now you’re going to say: Yes they can Exploiters can simply call :FireServer from their script executers

so we are just going round and round.

There isn’t a difference between :FireServer being called by a localscript in your game and it being called by an exploiter.

Exploiters can’t make it seem like the remote event was being fired by another player, they can’t change the first argument of .OnServerEvent.

I answered two different questions, I don’t quite understand what you are trying to say or what you are referring to by;

I think you understood where I was going right away … I guess proving me wrong is the only from of communication I’m going to get. You seem to know more than most so I’m looking for weaknesses in the hacking. You said the name can’t be faked with: “Exploiters can’t make it seem like the remote event was being fired by another player, they can’t change the first argument of .OnServerEvent .” and: “RemoteEvent:Connect(function(Player) --can’t be faked”

With some program checks that are not in the local scripts it’s should be hard to tell who just hacked what.

Standard security is to make sure a player asking for something from the server meets all the conditions on the server side. If they need to be in a certain location or have more than a certain amount of money, you check those things on the server so players can’t fudge them.

I go a step further in my projects and keep track of a Trust score for clients. Every time a client tries to do something wrong, that score goes down, and it gradually returns to normal over time. If it goes too low, some features don’t work, and if it goes even lower, they get kicked or even banned. Minor stuff that could be a result of ping or weird movement might be -3 trust, while sending obviously bad data to the server could be -50.

Hackers can change the code of any LocalScript - that includes changing the arguments of FireServer calls in their code. The first argument on the server side - the Player - isn’t from the LocalScript. It’s a feature of the RemoteEvent architecture that has the server check who “told” it that call.

If your RemoteEvent is set up to pass other data, that data can still be faked by exploiters, so it’s not something you want to accept blindly on the server.

1 Like

Can you show your code of what you’re doing now. This is more than the type of subject that should be focused on. This is just what I was thinking with the trust score check.

I was looking at OnServerInvoke along with .Changed:Connect(function() set up and got a few scripts that can return the name if the remote is fired. One is a local script but, the other actually sets off the remote and must meet a simple test to do so. The remote isn’t even there until the non-local script creates it. But, this is simple stuff and needs fine tuning. I wonder how the remote not being in folder on start up would effect the hacker’s ability to do anything, as it’s just there for that moment it’s called.

I use a ModuleScript in ServerScriptService to manage the system, and it keeps a score for each player in the game as a simple table. I also store the thresholds for certain actions in a table in the ModuleScript, which you’ll see referenced in the code snippet below. It’s entirely server-side, so players don’t get to know what their trust is or what it has to be to do certain things.

When a player does a bad thing, I just call a method on the server (not the client, clients have no access to this module) that decreases trust. That method looks like this - a lot of it just error checking.

function Trust:decreaseTrust(player:Player,amount:Number)
    if not amount or amount < 0 then
        warn("Bad Trust value passed to Trust module.")
        return
    end
    if not player then
        error("Player does not exist!")
    end
    if not trust[player] then
        warn("Trust value not found for player "..player.Name..". Creating new value from default.")
        trust[player] = BASE_TRUST --an internal integer for base trust everyone starts with
    end
    local rand = math.Random((-fudge/2),(fudge/2))
    amount = amount + rand
    if amount < 0 then
        amount = 0 --we don't want doing a bad thing to make you more trusted by accident
    end
    trust[player] = trust[player] - amount
    if trust[player] < KICK_THRESHOLD then
        player:Kick("You have been kicked from the game by anti-cheat systems.")
    end
end

When a player wants to do something game-changing, I run it through a method and looks like this.

function Trust:checkTrust(player:Player,action)
    if not player or not action then
        error("Invalid player or action request.")
    end
    if not trust[player] then
        error("Couldn't find a trust value for "..player.Name..".")
    end
    if not trustReqs[action] then
        error("Couldn't find a trust value for "..action..". Is it set properly?")
    end
    local rand = math.Random((-fudge/2),(fudge/2))
    --"fudge" is an internal value designed to make it harder for an exploiter to "probe" the system.
    --With it set high, moderation actions are less consistent, so they're harder to figure out.
    if trust[player] + rand > trustReqs[action] then
        return true
    else
        return false
    end
end

This may seem strange, but I rely a little on randomness. I don’t want people probing my system to figure out exactly what they’re allowed to do before being kicked, so when trust is reduced, and when I check trust, I “fudge” it a little, so sometimes an exploiter with low trust will just think the game is buggy or they have a bad connection.

trustReqs is a table that has a required trust value for a client to be allowed to do each thing. Opening doors to new rooms is important, so the value for it is set high, but being able to turn a flashlight on and off is less important, so even a likely exploiter can still do that.

4 Likes