Skip to content

Commit 048c72d

Browse files
azzyrsapphonie
andcommitted
Guard entity access behind ScriptCanAccess
Co-authored-by: sappho <sappho@sappho.io>
1 parent afcf3bc commit 048c72d

11 files changed

Lines changed: 70 additions & 14 deletions

src/game/client/c_basecombatweapon.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,3 +688,14 @@ void C_BaseCombatWeapon::GetToolRecordingState( KeyValues *msg )
688688
SetModelIndex( nModelIndex );
689689
}
690690
}
691+
692+
#ifdef MAPBASE_MP
693+
bool C_BaseCombatWeapon::ScriptCanAccess()
694+
{
695+
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
696+
if ( !pPlayer )
697+
return false;
698+
699+
return GetOwner() == pPlayer;
700+
}
701+
#endif

src/game/client/c_baseentity.cpp

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6689,21 +6689,12 @@ int C_BaseEntity::GetCreationTick() const
66896689
HSCRIPT C_BaseEntity::GetScriptInstance()
66906690
{
66916691
#ifdef MAPBASE_MP
6692-
// No clientside entity access outside of worldspawn + local player and its children
6693-
if ( this != C_BasePlayer::GetLocalPlayer() && !IsWorld() )
6692+
// client script should only touch a small whitelist of local player related ents.
6693+
// we can not naively grant access based on move-parent hierarchy, server-parented props used
6694+
// in the BadMDL exploit chain bypassed the old check that way. sorry.
6695+
if ( !ScriptCanAccess() )
66946696
{
6695-
// See if the player is somewhere up our hierarchy
6696-
C_BaseEntity *pParent = GetMoveParent();
6697-
while ( pParent )
6698-
{
6699-
if ( pParent != C_BasePlayer::GetLocalPlayer() )
6700-
pParent = pParent->GetMoveParent();
6701-
else
6702-
break;
6703-
}
6704-
6705-
if ( !pParent )
6706-
return NULL;
6697+
return NULL;
67076698
}
67086699
#endif
67096700

src/game/client/c_baseentity.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,10 @@ class C_BaseEntity : public IClientEntity
296296

297297
HSCRIPT GetScriptInstance();
298298

299+
#ifdef MAPBASE_MP
300+
virtual bool ScriptCanAccess() { return false; }
301+
#endif
302+
299303
HSCRIPT m_hScriptInstance;
300304
string_t m_iszScriptId;
301305
#ifdef MAPBASE_VSCRIPT

src/game/client/c_baseplayer.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3255,6 +3255,13 @@ C_ColorCorrection* C_BasePlayer::GetActiveColorCorrection() const
32553255
}
32563256
#endif
32573257

3258+
#ifdef MAPBASE_MP
3259+
bool C_BasePlayer::ScriptCanAccess()
3260+
{
3261+
return IsLocalPlayer();
3262+
}
3263+
#endif
3264+
32583265
//-----------------------------------------------------------------------------
32593266
// Purpose:
32603267
//-----------------------------------------------------------------------------

src/game/client/c_baseplayer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,10 @@ class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener
412412
C_ColorCorrection* GetActiveColorCorrection() const;
413413
#endif
414414

415+
#ifdef MAPBASE_MP
416+
virtual bool ScriptCanAccess() override;
417+
#endif
418+
415419
float GetFOVTime( void ){ return m_flFOVTime; }
416420

417421
virtual void OnAchievementAchieved( int iAchievement ) {}

src/game/client/c_baseviewmodel.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,3 +510,14 @@ RenderGroup_t C_BaseViewModel::GetRenderGroup()
510510
{
511511
return RENDER_GROUP_VIEW_MODEL_OPAQUE;
512512
}
513+
514+
#ifdef MAPBASE_MP
515+
bool C_BaseViewModel::ScriptCanAccess()
516+
{
517+
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
518+
if ( !pPlayer )
519+
return false;
520+
521+
return GetOwner() == pPlayer;
522+
}
523+
#endif

src/game/client/c_world.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ class C_World : public C_BaseEntity
5555
ScriptLanguage_t GetScriptLanguage() { return (ScriptLanguage_t)(m_iScriptLanguageClient != -2 ? m_iScriptLanguageClient : m_iScriptLanguageServer); }
5656
#endif
5757

58+
#ifdef MAPBASE_MP
59+
virtual bool ScriptCanAccess() override { return true; }
60+
#endif
61+
5862
public:
5963
enum
6064
{

src/game/shared/basecombatweapon_shared.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,10 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM
652652
//Tony; notifications of any third person switches.
653653
virtual void ThirdPersonSwitch( bool bThirdPerson ) {};
654654

655+
#if defined(CLIENT_DLL) && defined(MAPBASE_MP)
656+
virtual bool ScriptCanAccess() override;
657+
#endif
658+
655659
#endif // End client-only methods
656660

657661
virtual bool CanLower( void ) { return false; }

src/game/shared/baseviewmodel_shared.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ class CBaseViewModel : public CBaseAnimating, public IHasOwner
178178
virtual bool GetAttachmentVelocity( int number, Vector &originVel, Quaternion &angleVel );
179179
#endif
180180

181+
#ifdef MAPBASE_MP
182+
virtual bool ScriptCanAccess() override;
183+
#endif
184+
181185
private:
182186
CBaseViewModel( const CBaseViewModel & ); // not defined, not accessible
183187

src/game/shared/econ/econ_wearable.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,18 @@ bool CEconWearable::ShouldDraw( void )
405405
return BaseClass::ShouldDraw();
406406
}
407407

408+
#if defined(CLIENT_DLL) && defined(MAPBASE_MP)
409+
bool CEconWearable::ScriptCanAccess()
410+
{
411+
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
412+
if ( !pPlayer )
413+
return false;
414+
415+
// wearables use m_hOwnerEntity instead of m_hOwner
416+
return GetOwnerEntity() == pPlayer;
417+
}
418+
#endif
419+
408420
//-----------------------------------------------------------------------------
409421
// Purpose:
410422
//-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)