salty_tokenizer
Add security tokens to FiveM server events that are accessible from the client in order to prevent against Lua injections (and similar cheats).
Features
- A unique security token is generated for each resource each time the server is started. If the token is figured out by a cheater somehow, a restart will nullify their findings.
- Tokens can only be requested by the client once. This prevents a cheater from attempting to retrieve the token through a command.
- Players that trigger a server event without a valid security token are kicked from the game.
Installation
- A unique security token is generated for each resource on each server restart.
- Tokens are sent through listeners that are obfuscated per client and unique every time the player joins.
- Tokens can only be requested by the client once. This prevents a cheater from attempting to retrieve the token at a later time.
- Players that trigger a server event without a valid security token are kicked from the game.
Usage
The security token is stored in a variable named securityToken
on the client side in each resource. In order to retreive the security token for a given resource, you must include the init.lua
script in your resourceâs __resource.lua
file. The init.lua
script must be included as both a server and client script:
server_script '@salty_tokenizer/init.lua'
client_script '@salty_tokenizer/init.lua'
Note: If you implemented salty_tokenizer prior to the init.lua
script being released, it will continue to function normally and no changed need to be made.
Client
Once the token is received, it can be passed along with a server event to be validated on the server-side.
TriggerServerEvent('anticheat-testing:testEvent', securityToken)
Server
In order to protect a server event, a simple if statement must be added.
RegisterNetEvent('anticheat-testing:testEvent')
AddEventHandler('anticheat-testing:testEvent', function(token)
local _source = source
if not exports['salty_tokenizer']:secureServerEvent(GetCurrentResourceName(), _source, token) then
return false
end
print("Authenticated")
end)
This is expanded on in this post: [Release][DEV] Server Event Security Tokens - Anticheat
Deprecated Usage 9/5/2018
Usage
In order to use this resource, both the client and server scripts need adjusted.
Client
Tokens can be received by triggering an export once the tokenizer is ready.
local securityToken = nil
AddEventHandler('salty_tokenizer:clientReady', function()
securityToken = exports['salty_tokenizer']:setupClientResource(GetCurrentResourceName())
end)
Once the token is received, it can be passed along with a server event to be validated on the server-side.
TriggerServerEvent('anticheat-testing:testEvent', securityToken)
Server
To prepare a resource server side, an export must be called when the script is ready. Once this export is called, server events can be easily protected against abused server events.
AddEventHandler('salty_tokenizer:serverReady', function()
exports['salty_tokenizer']:setupServerResource(GetCurrentResourceName())
end)
In order to protect a server event, a simple if statement must be added.
RegisterNetEvent('anticheat-testing:testEvent')
AddEventHandler('anticheat-testing:testEvent', function(token)
local _source = source
if not exports['salty_tokenizer']:secureServerEvent(GetCurrentResourceName(), _source, token) then
return false
end
print("Authenticated")
end)
Deprecated Usage 8/1/2018
Usage
In order to use this resource, both the client and server scripts need adjusted.
Client
Tokens are received through the salty_tokenizer:receiveTokenClient
event on the client. A listener must be setup to store this security token.
local securityToken = nil
RegisterNetEvent('salty_tokenizer:receiveTokenClient')
AddEventHandler('salty_tokenizer:receiveTokenClient', function(receivedToken)
securityToken = receivedToken
end)
Events triggered with TriggerServerEvent
must now be modified to pass the security token along.
TriggerServerEvent('resource:securedEvent', securityToken)
Server
Tokens are received through the salty_tokenizer:receiveTokenServer
event on the server. A listener must be setup to store this security token.
local securityToken = nil
RegisterNetEvent('salty_tokenizer:receiveTokenServer')
AddEventHandler('salty_tokenizer:receiveTokenServer', function(receivedToken)
securityToken = receivedToken
end)
Events triggered from the client must now be modified to confirm the security token. If there is a security token mismatch, you may trigger the salty_tokenizer:invalidToken
event in order to kick the offending player: TriggerEvent('salty_tokenizer:invalidToken', _source)
RegisterNetEvent('resource:securedEvent')
AddEventHandler('resource:securedEvent', function(token)
local _source = source
if token ~= securityToken then
TriggerEvent('salty_tokenizer:invalidToken', _source)
return false
end
print("Authenticated")
end)
Download
Available on GitHub - https://github.com/SaltyGrandpa/salty_tokenizer