fix: team change message isn't broadcast on spawn#3237
fix: team change message isn't broadcast on spawn#3237lost-werewolf wants to merge 6 commits intoPryaxis:general-develfrom
Conversation
- fix player spawn bypassing pvp with no team - prevent malicious client from fast-switching with spawn packet - split up a check in HandlePlayerTeam to clarify debug message
Greptile SummaryThis PR fixes a security vulnerability where malicious clients could bypass the Key Changes:
Issues to Address:
Confidence Score: 3/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[PlayerSpawn packet received] --> B{pvpMode == pvpwithnoteam<br/>AND team != 0?}
B -->|Yes| C[Force team = 0<br/>Set teamCorrectNeeded]
B -->|No| D{Team change attempt<br/>AND < 5 sec since last?}
C --> D
D -->|Yes| E[Set teamCorrectNeeded]
D -->|No| F{First spawn?}
E --> F
F -->|Yes| G{Non-SSC AND<br/>team != 0 AND<br/>!teamCorrectNeeded?}
F -->|No| H{SSC enabled?}
G -->|Yes| I[Set InitialTeamChangePending<br/>LastPvPTeamChange = Now]
G -->|No| H
I --> H
H -->|Yes| J[SSC spawn path]
H -->|No| K[Non-SSC spawn path]
J --> L{team != TPlayer.team?}
K --> M{teamCorrectNeeded?}
L -->|Yes| N{teamCorrectNeeded?}
L -->|No| R[Spawn player]
N -->|Yes| O[BUG: team = TPlayer.team<br/>should enforce 0 for pvpwithnoteam]
N -->|No| P[Update LastPvPTeamChange]
O --> Q[TPlayer.team = team<br/>Broadcast spawn]
P --> Q
Q --> R
M -->|Yes| O
M -->|No| S{!InitialTeamChangePending<br/>AND team changed?}
S -->|Yes| T[Update LastPvPTeamChange]
S -->|No| U[TPlayer.team = team<br/>Broadcast spawn]
T --> U
R --> V{teamCorrectNeeded?}
U --> V
V -->|Yes| W[Send corrected team<br/>back to client]
V -->|No| X[Done]
W --> X
style O fill:#ffcccc
style C fill:#ccffcc
style E fill:#ffffcc
Last reviewed commit: 1736112 |
TShockAPI/GetDataHandlers.cs
Outdated
| if (teamCorrectNeeded) | ||
| { | ||
| team = (byte)args.Player.Team; | ||
| } |
There was a problem hiding this comment.
edge case bug: if pvpMode is "pvpwithnoteam" but args.Player.Team is somehow non-zero (e.g., admin changes pvpMode while players are online with teams), this will reset team to the player's current team instead of enforcing team 0. Consider preserving the forced team 0:
if (teamCorrectNeeded)
{
if (pvpMode == "pvpwithnoteam")
team = 0;
else
team = (byte)args.Player.Team;
}
TShockAPI/GetDataHandlers.cs
Outdated
| if (teamCorrectNeeded) // correction of malicious client's team change necessary | ||
| team = (byte)args.Player.Team; |
There was a problem hiding this comment.
same edge case as SSC path: if pvpMode is "pvpwithnoteam" and args.Player.Team is non-zero, this resets to the player's current team instead of enforcing 0. Apply the same fix as suggested for the SSC path.
fix typo Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
|
@greptile review? |
- correct player hostile flag & team in OnSecondUpdate - use separate message in HandleTogglePvp for pvp mode rejection
|
The edge case should be resolved by 55a819d, where I set the player's team to 0. Since it's already 0, there should be no edge case. Tested with a 3rd-party client using code execution to run code that sets my team and then spawns my player, I could not replicate anything. |
|
@greptile review |
|
I don't really see the edge case here. Since the player's team is always set to 0 when using |
|
Please do not use conventional commits. |
|
My apologies. if you can clarify what you mean by that, I will avoid it in the future. |
|
Better off closing and redoing this PR to squash everything into one commit? |
As a side effect of the change to handling of team in the
PlayerSpawnpacket, it now must handle the vanilla logic on its own, to prevent malicious clients from changing their team too fast, and to also prevent this from bypassing the "pvpwithnoteam" pvp mode.