Anti Event Tampering/ Triggering

Does anyone know if there is a resource out there to completely secure events like for each event and time its triggered there is a unique uuid that goes alone with it and it gets checked, as ive seen many of these bad actors have not only the event being triggered but the data that goes along with it so you can no longer use a single key per event

thanks

1 Like

Look up “event scramber” here on the forums, I’m not aware of any solution that would utilize a single-use unique key but at least you can scramble the names to make it easier, and act as a base for other features. Further work would have to be done by you to make them exactly what you want

1 Like

How do you plan on doing that, if current bad people can see and replicate what you send C->S. In fact, there is a tool in the client console that does exactly that! (showing the events, not the contents).

The most secure (and imo the only correct way) is to secure the events server-side, so clients can’t just trigger events however they want.

For example, here is an event that I use for a racing script, that gets triggered by the client whenever they reach a checkpoint in a race.

Here, I only give the server the checkpoint ID, then

  • I check if the player is actually in a tournament.
  • I Check if the player if actually racing, and if the race is not finished.
  • Then I check if the checkpoint that the client thinks it reached, is the same checkpoint that the server expects the client to reach.
  • Only then, I consider the event valid.

You can go even further than this and check server-side for the player’s coords, to make sure that they triggered the event in the correct place. And even save the time between checkpoints server-side to check for speed boosts.


This is how you should structure your scripts. Use the client for UI and gameplay related stuff, but only trust the server data when it comes to things like XP, money, or progression.

If you only use the server to save / load stuff (like how some frameworks used to do, and how many job resources still do to this day), then you only invite bad actors to take advantage of your server. The client should only request stuff, not decide on it.

Scrambling events can help, but not that much, since they can see whenever the event is triggered and corelate that to what the event does.

If the user receives $5000 at the end of the job, and the event viewer shows
TriggerServerEvent("N(_)V*$WngrHG(*7)GRE", 5000), you you exactly what it did.

3 Likes

Ah thank you for this,
For now I will try and do what you suggested and use good server logic to keep events secure, But I may look further into attempting to make a hook or something that can hopefully secure all events as I’ve seen a few servers plus my own use tunnel based logic say for giving weapons or setting armour and with a simple re run button it can happen again.

Once again thank you for your help

1 Like

It is not completely possible, the best way to secure your client events is to not trust them, see Secure your events - Cfx.re Docs for guide on how to secure your events.

IF you really really need to trust your client events (I can’t imagine such a scenario), then to answer your question there is such a resource, but it is not bulletproof and if the cheater is not a skid, then he will most likely be able to bypass it: [Release][DEV] Server Event Security Tokens - Anticheat - #14 by SaltyGrandpa

This is a great idea Crit! But Im curious, could there possibly be race conditions (heh!) if the player passes the checkpoint too quickly, or if the server is too bottlenecked? E.g. Player reaches and passes the checkpoint, and sends the event, but by the time the server processes the data, the player is long gone, and the server can’t TRULY validate the players position in the checkpoint?

I only ask because I’m dealing with a similar race condition in one of my scripts that’s similar to what you’re describing. E.g. Server can’t confirm player is in the appropriate position because by the time the player gets INTO teh position (and immediately out), it’s too late for the server to validate it?

Sorry to resurrect this one!
Thanks bud! :smiley:

First of all, great pun. But yeah, which is why in my case, when a player reaches the checkpoint, I put the client script into a “Waiting for server” state, until the server responds with the new data for the client to use.

In my case, the client is moved to status 99, and waits for the server to tell it to go back to status 2, for example.

(_lastUpdate is used here so the caption won’t flash the player for a ~10ms).

In this case I would cache the player position into a local variable in the event handler, as soon as the event is triggered (like, right after caching the source), and when checking for the player pos, I would also use a bigger radius check than on the client side. You can also get the player’s speed server-side, and decide the radius based on that (if the player isn’t moving, chances are they are still in the checkpoint).

Because server-side, the idea isn’t to have the same checks that are used for gameplay, but to make sure that the player doesn’t abuse the event.
If the player is 5 units away from the coords server-side, instead of 1 unit, that’s ok. Because it’s better than being 1000 units away, and spamming the event.
If this still doesn’t work for you, your players might be moving too fast, lol.

1 Like

Dude! This RUUUULES!

This gave me a bit more of a philosophical shift in perspective as well as some ideas. So thanks! This deserves its own post to be honest! <3

Either way, Thanks as always! :smiley:

This gave me a bit more of a philosophical shift in perspective as well as some ideas. So thanks! This deserves its own post to be honest! <3

Hi everyone I love to see that this discussion has got like minds thinking on best ways to protect events and the guide @CritteR suggested is really worth a look.

I have completed what I set out to-do and I’m just waiting on the pending release then i’ll link it here I have found a way to secure all events however measures should still be taken as suggested in this thread.

For now here is the preview and the explanation on how it works and how you may achieve a similar thing: