Server: properly rate limit client side script execution

Blocking it all together will cause problem when user wants to reset their controller binds. Now we limit execution to 4 per second (default) which doesn't cause problems when resetting any configuration, while also preventing cfg hacks.
This commit is contained in:
Kawe Mazidjatari 2023-12-30 17:31:55 +01:00
parent c5808e1117
commit b618daa694
3 changed files with 30 additions and 7 deletions

View File

@ -1495,6 +1495,10 @@ void CC_CreateFakePlayer_f(const CCommand& args)
}
#endif // !CLIENT_DLL
#ifndef DEDICATED
static double s_flScriptExecTimeBase = 0.0f;
static int s_nScriptExecCount = 0;
#endif // !DEDICATED
/*
=====================
Cmd_Exec_f
@ -1508,12 +1512,31 @@ void Cmd_Exec_f(const CCommand& args)
// Prevent users from running neo strafe commands and other quick hacks.
// TODO: when reBar becomes a thing, we should verify this function and
// flag users that patch them out.
if (!ThreadInServerFrameThread() && (!sv_allowClientSideCfgExec->GetBool() && g_pClientState->IsActive()))
if (!ThreadInServerFrameThread() && g_pClientState->IsActive())
{
DevWarning(eDLL_T::ENGINE, "Client is simulating and %s = false; dropped exec command: %s\n",
sv_allowClientSideCfgExec->GetName(), args.ArgS());
const int execQuota = sv_quota_scriptExecsPerSecond->GetInt();
return;
if (execQuota > 0)
{
const double flCurrentTime = Plat_FloatTime();
// Reset every second.
if ((flCurrentTime - s_flScriptExecTimeBase) > 1.0)
{
s_flScriptExecTimeBase = flCurrentTime;
s_nScriptExecCount = 0;
}
if (s_nScriptExecCount >= execQuota)
{
DevWarning(eDLL_T::ENGINE, "Client is simulating and exec count = %d of %d; dropped exec command: %s\n",
s_nScriptExecCount, execQuota, args.ArgS());
return;
}
s_nScriptExecCount++;
}
}
#endif // !DEDICATED
_Cmd_Exec_f(args);

View File

@ -171,7 +171,7 @@ ConVar* sv_rcon_maxpacketsize = nullptr;
ConVar* sv_rcon_whitelist_address = nullptr;
//#endif // DEDICATED
#endif // !CLIENT_DLL
ConVar* sv_allowClientSideCfgExec = nullptr;
ConVar* sv_quota_scriptExecsPerSecond = nullptr;
ConVar* sv_cheats = nullptr;
ConVar* sv_visualizetraces = nullptr;
ConVar* sv_visualizetraces_duration = nullptr;
@ -411,7 +411,7 @@ void ConVar_StaticInit(void)
sv_onlineAuthValidateIssuedAt = ConVar::StaticCreate("sv_onlineAuthValidateIssuedAt" , "1" , FCVAR_RELEASE, "Validate the online authentication token 'issued at' claim.", true, 0.f, true, 1.f, nullptr, nullptr);
sv_onlineAuthIssuedAtTolerance = ConVar::StaticCreate("sv_onlineAuthIssuedAtTolerance", "30", FCVAR_RELEASE, "The online authentication token 'issued at' claim tolerance in seconds.", true, 0.f, true, float(UINT8_MAX), nullptr, "Must range between [0,255]");
#endif // !CLIENT_DLL
sv_allowClientSideCfgExec = ConVar::StaticCreate("sv_allowClientSideCfgExec", "0", FCVAR_REPLICATED | FCVAR_RELEASE, "Allow clients to execute script files while being connected to this server.", false, 0.f, false, 0.f, nullptr, nullptr);
sv_quota_scriptExecsPerSecond = ConVar::StaticCreate("sv_quota_scriptExecsPerSecond", "4", FCVAR_REPLICATED | FCVAR_RELEASE, "How many script executions per second clients are allowed to submit, 0 to disable the limitation thereof.", true, 0.f, false, 0.f, nullptr, nullptr);
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)
bhit_depth_test = ConVar::StaticCreate("bhit_depth_test", "0", FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED, "Use depth test for bullet ray trace overlay.", false, 0.f, false, 0.f, nullptr, nullptr);
bhit_abs_origin = ConVar::StaticCreate("bhit_abs_origin", "1", FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED, "Draw entity's predicted abs origin upon bullet impact for trajectory debugging (requires 'r_visualizetraces' to be set!).", false, 0.f, false, 0.f, nullptr, nullptr);

View File

@ -161,7 +161,7 @@ extern ConVar* sv_rcon_maxpacketsize;
extern ConVar* sv_rcon_whitelist_address;
//#endif // DEDICATED
#endif // CLIENT_DLL
extern ConVar* sv_allowClientSideCfgExec;
extern ConVar* sv_quota_scriptExecsPerSecond;
extern ConVar* sv_cheats;
extern ConVar* sv_visualizetraces;
extern ConVar* sv_visualizetraces_duration;