Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

basic security resource as a foundation #528

Merged
merged 3 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions [admin]/security/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
*** DISCLAIMER ***

This resource is very barebone and should be used as a learning foundation for security on your server.
It only covers the most basic server events for detecting abusive behaviour and logs them without taking any action.
There are many more ways to combat bad players with server and client scripting adapted to your server/gamemode.

As a general rule of thumb, following points should be considered:
- never trust the client, if you accept data from client, validate it on server if they make any sense
- use the variable "client" instead of "source" for custom server events, source can be faked, client not
- try to avoid elementdatas, if you need elementdata to be synced to client and they should remain read only on client,
add them to tblProtectedElementDatas in players.lua to prevent clients from updating them
15 changes: 15 additions & 0 deletions [admin]/security/events.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- https://wiki.multitheftauto.com/wiki/OnPlayerTriggerInvalidEvent
-- gets triggered when a remote clients triggers an invalid event on server
function clientTriggersInvalidEvent(strEventName, bIsAdded, bIsRemote)
logViolation(source, "Triggered invalid event \""..strEventName.."\" - bIsAdded: "..tostring(bIsAdded).." - bIsRemote: "..tostring(bIsRemote));
end
addEventHandler("onPlayerTriggerInvalidEvent", root, clientTriggersInvalidEvent);



-- https://wiki.multitheftauto.com/wiki/OnPlayerTriggerEventThreshold
-- gets triggered when a remote clients exceeds the event trigger treshold set by server in config -> max_player_triggered_events_per_interval
function clientTriggersEventThreshold()
logViolation(source, "Exceeded event trigger threshold of "..tostring(getServerConfigSetting("max_player_triggered_events_per_interval")));
end
addEventHandler("onPlayerTriggerEventThreshold", root, clientTriggersEventThreshold);
65 changes: 65 additions & 0 deletions [admin]/security/logging.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
-- log messages triggered by player
function logViolation(uPlayer, strMessage)
local strPlayerName, strPlayerIP, strPlayerSerial = getPlayerName(uPlayer), getPlayerIP(uPlayer), getPlayerSerial(uPlayer);
local strLogFileName = "violations.txt";
local uFileHandle = fileExists(strLogFileName) and fileOpen(strLogFileName);

if(not uFileHandle) then
uFileHandle = fileCreate(strLogFileName);
fileFlush(uFileHandle);
else
fileSetPos(uFileHandle, fileGetSize(uFileHandle));
end

local strViolationMessage = getDateTime().." CLIENT: "..strPlayerName.." | IP: "..strPlayerIP.." | SERIAL: "..strPlayerSerial.." | "..strMessage;

outputDebugString(strViolationMessage, 4, 255, 255, 255);
outputServerLog(strViolationMessage);
fileWrite(uFileHandle, strViolationMessage.."\n");
fileFlush(uFileHandle);
ffsPLASMA marked this conversation as resolved.
Show resolved Hide resolved
fileClose(uFileHandle);
end



-- log messages without player element
function logAction(strMessage)
local strLogFileName = "actions.txt";
local uFileHandle = fileExists(strLogFileName) and fileOpen(strLogFileName);

if(not uFileHandle) then
uFileHandle = fileCreate(strLogFileName);
fileFlush(uFileHandle);
else
fileSetPos(uFileHandle, fileGetSize(uFileHandle));
end

local strActionMessage = getDateTime().." "..strMessage;

outputDebugString(strActionMessage, 4, 255, 255, 255);
outputServerLog(strActionMessage);
fileWrite(uFileHandle, strActionMessage.."\n");
fileFlush(uFileHandle);
ffsPLASMA marked this conversation as resolved.
Show resolved Hide resolved
fileClose(uFileHandle);
end



-- get the current date and time for logging
function getDateTime()
local tblRealTime = getRealTime();
local iDay = tblRealTime.monthday;
local iMonth = tblRealTime.month + 1;
local iYear = tblRealTime.year + 1900;
local iHour = tblRealTime.hour;
local iMinute = tblRealTime.minute;
local iSecond = tblRealTime.second;

if(iDay < 10) then iDay = "0"..iDay end;
if(iMonth < 10) then iMonth = "0"..iMonth end;
if(iHour < 10) then iHour = "0"..iHour end;
if(iMinute < 10) then iMinute = "0"..iMinute end;
if(iSecond < 10) then iSecond = "0"..iSecond end;

return "["..tostring(iDay).."."..tostring(iMonth).."."..tostring(iYear).." - "..tostring(iHour)..":"..tostring(iMinute)..":"..tostring(iSecond).."]";
ffsPLASMA marked this conversation as resolved.
Show resolved Hide resolved
end
10 changes: 10 additions & 0 deletions [admin]/security/meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<meta>
<info name="Security" author="-ffs-PLASMA" type="misc" version="1.0" description="Basic security functionality" />

<min_mta_version server="1.6.0-9.22470" />

<script src="logging.lua" type="server"/>
<script src="events.lua" type="server"/>
<script src="misc.lua" type="server"/>
<script src="players.lua" type="server"/>
</meta>
15 changes: 15 additions & 0 deletions [admin]/security/misc.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- https://wiki.multitheftauto.com/wiki/OnSettingChange
-- gets triggered when a resource setting has been changed
function resourceSettingChanged(strSetting, strOldValue, strNewValue)
logAction("Setting \""..strSetting.."\" has been changed from \""..fromJSON(strOldValue).."\" to \""..fromJSON(strNewValue).."\"");
end
addEventHandler("onSettingChange", root, resourceSettingChanged);



-- https://wiki.multitheftauto.com/wiki/OnAccountDataChange
-- gets triggered when account has been changed
function accountDataChanged(uAccount, strKey, strValue)
logAction("Data \""..strKey.."\" of account \""..getAccountName(uAccount).."\" has been changed to \""..strValue.."\"");
end
addEventHandler("onAccountDataChange", root, accountDataChanged);
58 changes: 58 additions & 0 deletions [admin]/security/players.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
-- add the elementdatas you want to protect from client updates in here
local tblProtectedElementDatas = {["Score"] = true};



-- https://wiki.multitheftauto.com/wiki/OnElementDataChange
-- gets triggered when a client tries to change a synced elementdata, check if client is permitted to change that specific data
-- also prevents one client changing the elementdata of another client
function clientChangesElementData(strKey, varOldValue, varNewValue)
if(client and (tblProtectedElementDatas[strKey] or client ~= source)) then
logViolation(client, "Tried to change elementdata \""..tostring(strKey).."\" of resource \""..tostring(sourceResource).."\" from \""..tostring(varOldValue).."\" to \""..tostring(varNewValue).."\"");
setElementData(source, strKey, varOldValue);
end
end
addEventHandler("onElementDataChange", root, clientChangesElementData);



-- https://wiki.multitheftauto.com/wiki/OnPlayerACInfo
-- gets triggered when AC detects something for client on connect
function clientNotifyACInfo(tblDetectedACList, iD3D9Size, strD3D9MD5, strD3D9SHA256)
logViolation(source, "AC list detected: "..table.concat(tblDetectedACList, ",").." - D3D9Size: "..tostring(iD3D9Size).." - D3D9MD5: "..tostring(strD3D9MD5));
end
addEventHandler("onPlayerACInfo", root, clientNotifyACInfo);



-- https://wiki.multitheftauto.com/wiki/OnPlayerModInfo
-- gets triggered when client joins server with modified game files
function clientNotifyModInfo(strFileName, tblItemList)
for _, strItemName in ipairs(tblItemList) do
logViolation(source, "Mod detected - file: "..strFileName.." - GTA ID: "..strItemName.id.." - GTA name: "..strItemName.name);
end
end
addEventHandler("onPlayerModInfo", root, clientNotifyModInfo);



-- force all connected players to send their AC/Mod info on resource start
addEventHandler("onResourceStart", resourceRoot, function()
for _, uPlayer in ipairs(getElementsByType("player")) do
resendPlayerModInfo(uPlayer);
resendPlayerACInfo(uPlayer);
end
end);



-- https://wiki.multitheftauto.com/wiki/OnPlayerNetworkStatus
-- gets triggered when connection from server to a client is interrupted
function clientNetworkStatus(iStatus, iTicks)
if(iStatus == 0) then
logViolation(source, "Network interruption has began after "..iTicks.." ticks");
elseif(iStatus == 1) then
logViolation(source, "Network interruption has stopped after "..iTicks.." ticks");
end
ffsPLASMA marked this conversation as resolved.
Show resolved Hide resolved
end
addEventHandler("onPlayerNetworkStatus", root, clientNetworkStatus);