The following code has been tested in dedicated server environment and all works.
The premise.
It is not unfeasible to think that even with security measures like Battleye and Steam own protection someone would still be able to run custom code on their client at some point. If the malicious code effect is only limited to the client then it could be treated as minor inconvenience. However if the hacker is able to execute the code globally on every PC, this becomes a serious problem. Having access to the server this way is a massive security concern.
What we have now.
There are at least 3 ways the hacker can exploit the system right now to execute his code globally.
- Old unit creation command which allows to have init param executed globally. A similar problem existed with vehicleInit command, which has been removed for this very reason, yet the old create unit format exists and thrives. The only backwards compatibility it offers is for the hacker to run his hacks with ease, considering this hack trick is one of the oldest.
Example:
Hacker runs this code on client once:
"Rabbit_F" createUnit [[0,0,0], group player, "'hack' addPublicVariableEventHandler {call (_this select 1)}"];
And then can repeatedly execute his malicious code with:
hack = {/*hackedcode*/}; publicVariable "hack";
Solutions:
a. Remove this format completely. createUnit_array is a good alternative and uses the same format as createAgent and createVehicle
b. Make init param require name of the function, so instead of (call compile "") make it (execVM "")
- Global MP event handlers. Code in MPKilled, MPHit and MPRespawn EH is executed globally (MPRespawn is bugged atm and server execution is excluded from it). So by attaching a MP event handler to his unit and dying hacker can plant his base code on every PC.
Example:
Hacker runs this code on client once then kills himself:
player addMPEventHandler ["MPKilled", "'hack2' addPublicVariableEventHandler {call (_this select 1)}"];
He then can repeatedly execute his code with:
hack2 = {/*hackedcode*/}; publicVariable "hack2";
Solutions:
a. Limit EH execution to the PC it was set on, just like many other EH can already do. i.e. change effect from global to local.
b. Make it require and call function name instead of code.
- While BIS_fnc_MP is pretty well written and only allows of passing function name instead of code, what good is it if BIS officially provides 2 functions (bis_fnc_spawn and bis_fnc_call) to just remote execute any code?
Example:
Hacker can run this code repeatedly. He can also set additional 4th param to make it persistent to welcome all newly joined players to his hack:
[{/*hackedcode*/},"BIS_fnc_spawn",true] call BIS_fnc_MP;
[{/*hackedcode*/},"BIS_fnc_call",true] call BIS_fnc_MP;
Solution:
Remove both BIS_fnc_spawn and BIS_fnc_call functions, there is no other way.
Tnanks