Best practices for preventing common exploits?

Whenever I fire a remote event/function, I tend to include a key of random characters as one of the arguments and then in the second script, I check to see if the argument passed is the correct key, potentially thwarting someone trying to fire an event through a command line to, for example, kill someone with a ‘take damage’ event.

2 Likes

Lol I see these threads every other day.

I think as @EmeraldSlash says, starting out with filtering enabled is a pretty good move. Having your code manually record movement, and checking if there is some sort of transition between two points, could help you determine wether a player is exploiting.

Thought bubbles:

  • Max player “on-foot” speed.

  • Not allowing the player to even appear in a position outside of the “range” of the position they were x seconds ago.

  • Utilizing the navigation mesh to find if a player can get to an area, or if it is solid, so as not to allow the player to be in it.

  • Having Manual “no-go zones” that push you right out if you are within a region.

  • Dropping a block every few milliseconds at the players position, then getting the magnitude between the “markers” and measuring if they exceeded their max moving distance.

Keep in mind that you have to make sure your methods aren’t hackable themselves. (FE will help a lot here)

Keep experimenting!

2 Likes

A problem here would be Lag if you needed to teleport a user. My fix is to check a player’s ping and factor it in with my antiexploit. It works very well I have yet to be falsely kicked from my anti exploit

3 Likes

As a blanket statement, let’s assume everyone here is using FilteringEnabled. You’re literally not going to be making a successful game without it, thus no need to mention it for now.


So it sounds like the gist of it is the same as it has always been: don’t trust the client at all. It sounds like the “trust” part of the equation is going to vary from game-to-game. For instance, in an FPS, you might need to perform some sanity checks on how often a player is shooting a gun.

Also, just in case you missed it, all games are now FilteringEnabled (it was forced by Roblox a few months ago!)

3 Likes

Untrusted data should go through a few steps:

  1. Rate limiting
  2. Schema validation
    • e.g. type assertions
  3. Sanity checks
    • e.g. discarding OOB or nonfinite values
  4. Optional: Turing tests
    • e.g. calling out aimbots

A cool problem that @0xBAADF00D and I ran into yesterday is NaN poisoning. If a malicious user can introduce a NaN into your game’s economy, they might be able to get infinite items for free depending on how your code is structured:

-- Unsafe: NaN balance will award item
if player.balance < price then
    print("not enough money!")
else
    awardItem()
end
-- Safe: NaN balance won't award item
if player.balance >= price then
    awardItem()
else
    print("not enough money!")
end
22 Likes

Wouldn’t the easy solution be to just listen for when the user wants to buy something, and what they want, but never let them try telling you what their balance is? Keep all that stuff serverside and send the client an updated value any time it changes serverside so they can still display it.

3 Likes

I’m curious to know what these checks on the client by @einsteinK even do xd
(I assume that you can access these things in a level 7 but why can the clients not require your modules in a lower level environment?)

local function checks()
	-- einsteink hack checks https://devforum.roblox.com/t/anti-exploit-draft-mostly-re-rf-protection/32253
	assert(not pcall(function() return workspace.DataCost end))
	assert(not pcall(function() return workspace.RobloxLocked end))
	assert(not pcall(function() return game:GetService("CoreGui").Name end))
	assert(not pcall(function() return game:GetService("CoreGui").SelectionImageObject end))
	assert(not pcall(function() return game:GetService("Chat"):GetShouldUseLuaChat() end))
end

I don’t know how this sounds…but:

Don’t exploiters mainly change variables for their benefit? Or insert scripts? Well, you could basically have a script manage when/what is allowed to change it. Only x script can change xyz variables. Detect new “children” scripts, and delete them if they weren’t original (or added by the game.)

2 Likes

I tell the server I want to buy NaN things. The server agrees and deducts NaN from my balance. I have NaN money now.

1 Like

Oh! I see now.

that check wouldn’t matter really (only if done locally) considering the actual data would be used, not anything from client

I have some questions that I am hoping someone can answer. This would be helpful to know if these are possible exploits or not. Is it possible for a hacker to send events to/from other players?

  1. Is it possible for a hacker to send a bogus remote event from the server to another player?
    For example, they would mimic a server to client event that affects another player.

  2. Is it possible for a hacker to send a bogus remote event from another player to the server?
    For example, they would mimic a client to server event that affects another player.

Exploiters can do anything a script can do on their client. I am not sure what happens if they send an event that doesnt exist on the server, but I would guess it would send.

Edit; It doesnt really matter, any events they send that dont exist on server will simply do nothing. They may be able to spam the event to overload data requests though.

No, there’s no way for hackers to do that if you’re using remotes correctly.

3 Likes

Yea but how does it happen

From what I understand, @Fractality_alt is saying in certain circumstances a user can pick the quantity of what they want to buy, then of course the server multiplies the price of the item by the quantity. If the quantity is NaN, then NaN balance is removed. Of course the server finds the price of the item in question itself, it’s just that if you let the client decide quantity of what it’s buying without sanity checks it can be exploited very easily, and in some cases despite having a sanity check in place there’s a hole still.

This hasn’t been an effective way of checking for raised contexts for years. Exploits aren’t naively setting the context level of LocalScripts.

Yea but stuff like that should already be checked for. If you assume whatever client sends is going to be what theyre supposed to send then you still havent fully understood the concept of FE. Simple checks for something like that might include num==num and num>0 and num~=1/0 and floor(num) and so on

Yeah, which is what he was saying. The importance of what he said is how you check your quantity, rather than whether or not you do.