I “solved” this age old problem with a sort of elegant solution. While you can never truly secure RemoteEvents, the solution I came up with will deter most of the exploiters who just watch YouTube videos on how to haxx adopt mee and have no real programming experience, or any idea of what they’re doing in general. I’ll outline my systems below:
Event name scrambling
This one is pretty common. This involves storing a cache of the RemoteEvent objects alongside the original names somewhere secure, like the server. Then ever second or so you rename each event to a GUID. This along deters most exploiters because while they can still see the traffic of the RemoteEvents, the names will always be changing, making it incredibly hard to track down specific events.
In my application the server holds the master list between the original event name, and it’s physical object in ReplicatedStorage. The server is also the one scrambling the names. This ensures the clients can’t stop the scrambling. When the client joins the game, it invokes one remote function that isn’t scrambled. This function returns the list of RemoteEvents and their objects. The server then marks that they’ve called it and won’t allow them to call that again.
Note: I use a custom NetworkingService that ties all these things together.
Rotating key argument
This one is fantastic. This involves the internal NetworkingService attaching a GUID alongside the event that’s fired. This is different than a password because those aren’t secure and are genuinely pointless. Every time an event is fired, the server returns a new GUID. It expects this to be send back when that event is fired again. If they don’t match, the server throws out the request. These GUID’s are unique to each RemoteEvent and rotate each time they invoke.
This is important because while the GUID’s are visible to the exploiters*, they are meaningless without an explanation. If a key is sent more than once, the events won’t go through.
Note: Upon testing this solution with Synapse, I found that whatever version of RemoteSpy I was using failed to present the data returned in a RemoteFunction. I was able to see the initial request and it’s data, but anything returned by the server was not visible. If this is the case with all current versions of RemoteSpy, it’s essentially impossible to know what they next GUID is.
Things to know
You cannot store anything in a module. The list of RemoteEvents to Objects, the master GUID table on the client etc. All of these things must be stored in private variables so they’re not accessible by any malicious actors.
Final remarks
Like I said at the beginning, you can never truly secure RemoteEvents / RemoteFunctions. These solutions just deter a lot of malicious actors from perusing more exploits in your game. I only recommend these solutions if you’re experienced with writing internal libraries such as NetworkingServies and whatnot. These systems can fail incredibly easily if not setup properly. I’ve fine tuned my module to work reliably, without problems. If you have any questions please let me know.