I couldn’t find an answer to this anywhere else so I decided this would be a good place.
Right now currently I have a Module Script that contains all the functions of the parts and whatnot.
My main script which is a server script calls the remote event then the client script gets that call and calls the functions of the module scripts.
My question is, can an exploiter abuse it if the call is done from the server while the action is done on the client?
Exploiters can listen for any server calls on any event via an injected client script. They can read any arguments passed through as well. They can only read what is fired to them, though. So, if you use Event:FireAllClients(), naturally, anyone listening for Event.OnClientEvent will be able to read it, whether malicious or not. If you’re sending sensitive data, be sure to only fire the client you need to have the data. Make sure that any time you use :FireServer() that the server checks whatever arguments you’ve passed to ensure that they’re valid and that they won’t cause any harm, as exploiters can also call :FireServer() on any event you have.
Think of it this way: Anything a LocalScript can do, an exploiter can do. So, if you want to keep your game secure, NEVER trust the client and ALWAYS check on the server that what they communicate to the server is VALID and CORRECT and won’t cause any harm before the server does anything with the data.
Wait so, If I were to have all the functions on a module script. Then call the functions on the Client whenever the remote event is called from the server, could they abuse it? (Also, the information isnt really important, it just calls to make sure the parts have their right functions whenever the map is cloned into workspace)
Edit: I was really just asking this as a question since I was afraid that an exploiter could use the remote event and mess up alot of things on the server side for other players or break the game.
To add ontop this;
Exploiter’s have the ability to modify and call functions/variables inside of local scripts, never trust values from the client when invoking to the server unless you have a method to verify them.
What I mean by this is…
If the client invokes to the server that PLAYER_1 has 50 gold from a variable like: local Gold = 50
An exploiter has the ability to modify this to whatever he wants.
Keep in mind that any code in a ModuleScript is readable from both the client and the server, unless said script is in ServerScriptService or ServerStorage. Any script can require() a ModuleScript and its code will run. So, make sure there is no sensitive data (e.g. api keys) hardcoded into ModuleScripts accessible from the client.
As for protecting events, like I said, double check the values on the server. For example, if someone wants to buy something, and they fire BuyEvent:FireServer("itemName"), check on the SERVER that they have enough money to buy itemName, even if the client thinks they have enough money. Anything that can change the environment for others should be double checked by the server that the environment is allowed to be changed by the client that’s trying to change it.
Any exploiter can fire the event with any value, and they might use it to buy everything for free if you don’t implement a safeguard for that. Defensive scripting is a must, and it should all happen on the server side. Protecting events is how you protect your game from exploiters.
Again, that means however you were letting the client manipulate their coin balance wasn’t double checked by the server. If the server just blindly accepts any value given to them by the client, then the client has full control over what the server does. You need to ensure that the server has full control over what the client does by keeping the client in check. Make sure the client passes the exact correct values. If it doesn’t, assume the client is wrong and ignore it. The server should be the one calling the shots when it comes to seeing if the client has permission to do something.
If the server detects something weird about what the client passed to the server, for example the client is trying to spend -10000 coins, then the server should flag that and say “that’s not allowed” and ignore it. etc
It’s on a case by case basis. Ensure that on every event the client could fire that the server double checks the arguments the client sent. Make sure there’s nothing weird in the arguments and that the client is allowed to do what it’s trying to do.
And the local script uses that call to get the functions from the module script, You’re saying that the client can read anything in a module script? If so, could the player keep calling the same event even though the server is the one calling the events and the client calls the functions? Because all I’m doing is when my minigame script runs into a certain stage, it calls the remote event, which tells the client to reload the assets with functions. But the client doesnt call the remote event at all. It only listens to it?
A client can only use Event:FireServer() and Event.OnClientEvent. The client cannot call :FireClient() or :FireAllClients() on any event, nor can it read Event.OnServerEvent. All a client can do is listen for events from the server or send an event to the server. The client cannot send data between clients without going through the server first. Therefore, the server should act as a filter between clients, and it’s your job as a scripter to create that filter and only let through what your game decides is allowed to be let through.
No problem, glad we could help. If you’re interested in reading more about how clients can interact with the server and how to replicate things between clients, I recommend checking out this article on the Roblox DevHub to gain a deeper understanding of how Roblox lets clients communicate.