fix: security vulnerabilities

Tested that all functions related to the touched files work

will test sqlite on a CI build
This commit is contained in:
David Markowitz
2026-06-06 23:13:09 -07:00
parent 8e09ffd6e8
commit fb166bd24d
107 changed files with 786 additions and 512 deletions

View File

@@ -30,6 +30,21 @@ void AirMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream& bitS
return;
}
// So a player can't send an arbitrary behaviorID in a modified client and cast any behavior on any air behavior
Behavior* toSync = nullptr;
if (m_GroundAction->GetBehaviorID() == behaviorId) {
toSync = m_GroundAction;
} else if (m_HitAction->GetBehaviorID() == behaviorId) {
toSync = m_HitAction;
} else if (m_HitActionEnemy->GetBehaviorID() == behaviorId) {
toSync = m_HitActionEnemy;
} else if (m_TimeoutAction->GetBehaviorID() == behaviorId) {
toSync = m_TimeoutAction;
} else {
LOG("Invalid Air Movement Behavior sync for behaviorID %i on behavior %i", behaviorId, m_behaviorId);
return;
}
LWOOBJID target{};
if (!bitStream.Read(target)) {
@@ -37,15 +52,17 @@ void AirMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream& bitS
return;
}
auto* behavior = CreateBehavior(behaviorId);
if (Game::entityManager->GetEntity(target) != nullptr) {
branch.target = target;
}
behavior->Handle(context, bitStream, branch);
toSync->Handle(context, bitStream, branch);
}
void AirMovementBehavior::Load() {
this->m_Timeout = (GetFloat("timeout_ms") / 1000.0f);
m_Timeout = (GetFloat("timeout_ms") / 1000.0f);
m_GroundAction = GetAction("ground_action");
m_HitAction = GetAction("hit_action");
m_HitActionEnemy = GetAction("hit_action_enemy");
m_TimeoutAction = GetAction("timeout_action");
}

View File

@@ -15,4 +15,9 @@ public:
void Load() override;
private:
float m_Timeout;
Behavior* m_GroundAction{};
Behavior* m_HitAction{};
Behavior* m_HitActionEnemy{};
Behavior* m_TimeoutAction{};
};

View File

@@ -42,6 +42,7 @@ void AreaOfEffectBehavior::Handle(BehaviorContext* context, RakNet::BitStream& b
LWOOBJID target{};
if (!bitStream.Read(target)) {
LOG("failed to read in target %i from bitStream, aborting target Handle!", i);
continue;
};
targets.push_back(target);
}

View File

@@ -68,7 +68,7 @@ void BasicAttackBehavior::DoHandleBehavior(BehaviorContext* context, RakNet::Bit
}
if (isBlocked) {
destroyableComponent->SetAttacksToBlock(std::min(destroyableComponent->GetAttacksToBlock() - 1, 0U));
destroyableComponent->SetAttacksToBlock(std::max<int32_t>(static_cast<int32_t>(destroyableComponent->GetAttacksToBlock() - 1), 0));
Game::entityManager->SerializeEntity(targetEntity);
this->m_OnFailBlocked->Handle(context, bitStream, branch);
return;
@@ -103,9 +103,10 @@ void BasicAttackBehavior::DoHandleBehavior(BehaviorContext* context, RakNet::Bit
return;
}
uint32_t totalDamageDealt = armorDamageDealt + healthDamageDealt;
uint64_t totalDamageDealt = armorDamageDealt + healthDamageDealt;
// A value that's too large may be a cheating attempt, so we set it to MIN
// Can't overflow here either because should we somehow get to a 64 bit number it'll be clamped to a sane value.
if (totalDamageDealt > this->m_MaxDamage) {
totalDamageDealt = this->m_MinDamage;
}

View File

@@ -48,15 +48,13 @@ void BlockBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branc
return;
}
auto* destroyableComponent = entity->GetComponent<DestroyableComponent>();
auto* const destroyableComponent = entity->GetComponent<DestroyableComponent>();
destroyableComponent->SetAttacksToBlock(this->m_numAttacksCanBlock);
if (destroyableComponent == nullptr) {
return;
if (destroyableComponent) {
// ??? what is going on here?
destroyableComponent->SetAttacksToBlock(this->m_numAttacksCanBlock);
destroyableComponent->SetAttacksToBlock(0);
}
destroyableComponent->SetAttacksToBlock(0);
}
void BlockBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) {

View File

@@ -11,6 +11,11 @@ void ChainBehavior::Handle(BehaviorContext* context, RakNet::BitStream& bitStrea
return;
}
if (chainIndex == 0) {
LOG("Received invalid chain index of 0 for behavior %i.", m_behaviorId);
return;
}
chainIndex--;
if (chainIndex < this->m_behaviors.size()) {

View File

@@ -7,6 +7,7 @@
void JetPackBehavior::Handle(BehaviorContext* context, RakNet::BitStream& bit_stream, const BehaviorBranchContext branch) {
auto* entity = Game::entityManager->GetEntity(branch.target);
if (!entity) return;
GameMessages::SendSetJetPackMode(entity, true, this->m_BypassChecks, this->m_EnableHover, this->m_effectId, this->m_Airspeed, this->m_MaxAirspeed, this->m_VerticalVelocity, this->m_WarningEffectID);
@@ -21,6 +22,7 @@ void JetPackBehavior::Handle(BehaviorContext* context, RakNet::BitStream& bit_st
void JetPackBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
auto* entity = Game::entityManager->GetEntity(branch.target);
if (!entity) return;
GameMessages::SendSetJetPackMode(entity, false);

View File

@@ -17,6 +17,11 @@ void SwitchMultipleBehavior::Handle(BehaviorContext* context, RakNet::BitStream&
return;
};
if (m_behaviors.empty()) {
LOG("No behaviors were loaded for %i, aborting call.", m_behaviorId);
return;
}
uint32_t trigger = 0;
for (unsigned int i = 0; i < this->m_behaviors.size(); i++) {