Client destruction of character objects replicates to server

While developing an anticheat, I discovered that exploiters can destroy any individual object in their characters, including non-physical items like decals, joints, and scripts, and that destruction replicates to the server. This behavior is also not documented where it should be.

This can happen pretty much everywhere that uses the default characters familiar to Roblox players, and is not limited to Roblox Studio.

For example, if I run this script on my client, my limbs and t-shirt disappear on both client and server.

local character = game.Players.LocalPlayer.Character
character.LeftUpperArm:Destroy()
character.RightUpperArm:Destroy()
character.LeftUpperLeg:Destroy()
character.RightUpperLeg:Destroy()
character["Shirt Graphic"]:Destroy()



Edit:

I did some more searching, and it turns out this is an old issue.

24 Likes

You could have a script that checks through player’s characters to see if everything is still intact, and if not, you could reset them?
For clothing, you could have a table with what the player originally joined with. To prevent false firings for if a player resets with a new article of clothing, just update the table every time a player resets.

I’m not an expert on this, so there might be a better way to do this.

3 Likes

The issue is them being able to cross the client-server barrier.

5 Likes

Of course, what I posted is just a suggestion for a temporary fix!

2 Likes

I can also reproduce this:

local character = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()

character:WaitForChild("LeftUpperArm"):Destroy()
character.RightUpperArm:Destroy()
character.LeftUpperLeg:Destroy()
character.RightUpperLeg:Destroy()
2 Likes

Aw crud. I rely on StarterCharacterScripts a lot. This definitely needs to be fixed.

3 Likes

This could potentially break server scripts, if they happen to rely on things like limbs existing.

2 Likes

This also applies to objects you insert. So if your game has “Health” and “Mana” values for example, they can delete these and break your scripts.

Don’t store anything in the Character (even though it’s the most intuitive place) :confused:

I made a proposal before to add a new property to fix this a while back:

12 Likes

big brain above, and exploiters can manipulate unanchored parts, and tools with weird results.
This is mostly for cosmetics.

1 Like

I think the reason for this is so that character movements replicate instantly, but I agree this should not happen to all objects parented to the player. (You can also cause your character to respawn by deleting the humanoid object on the client which could break some games).

3 Likes

It’s possible to teleport other players if there’s a skateboard in the game. Exploiters can teleport the skateboard to the player and then teleport it where they want to player to go. Not sure if this works with seats as well but this is a severe issue.

1 Like

If I knew this was intentional behavior, I wouldn’t have filed the issue as a bug.

But then again, why is it not stated in the developer wiki?

1 Like

Personally I think that this is a bug, especially considering it’s not documented and new developers will put stuff in the character (because this is intuitive).

I made that feature request because this bug has been around & reported so for so long that it’s likely considered “legacy support” by now :confused:

7 Likes

Hey could you please explain how putting values or “stuff” in the Character is intuitive?
I’ve never done that even as a “new” developer because I always thought it’s not right…

1 Like

Putting stuff there is useful because you can alter the character’s behavior without having to copy the whole character or do complicated scripting systems. For example, if you wanted the character to use custom swimming behavior, you could put in a LocalScript that does that.

1 Like

That doesn’t make sense, checking when the player respawns isn’t complicated it’s just Player.CharacterAdded but that doesn’t really matter since like you said a LocalScript which obviously could be deleted by the client so I see no reason for “Putting stuff in the Character” to be used an argument or a reason…
I’ve been working on 3 games and none of them have any scripts that are inside the Character because there is no reason for them to be there, there is no reason to store values/important values.

All my scripts are mostly inside ReplicatedFirst

1 Like

Some tips for avoiding the consequences of this bug:

  • If your game has a custom nametag system with BillboardGuis, don’t parent them to the character. Use PlayerGui instead.
  • If you do store any Values under the character, make sure to check for their presence before indexing them directly.
  • Humanoid-less (custom) characters are still vulnerable as long as plr.Character property references the character model
  • If the player removes any vital instance, respawn them or act like they died
  • Don’t forget parts can be removed by other sources too, such as FallenPartsDestroyHeight
15 Likes

This is hugely problematic, and needs to be fixed ASAP. If this is intentional behavior, it must be documented immediately.

I think this is almost definitely a bug, considering other non-physics changes made on the client don’t seem to replicate, as expected.

1 Like

If it was not a bug, then what would even be the point of having StarterCharacterScripts? It becomes effectively useless.

1 Like

Roblox stores Health, WalkSpeed, and plenty of other properties about your character in the Humanoid. This is automatically replaced when you reset with the StarterCharacter, so if you wanted to add a “Mana” value or “Ammo”, etc, then you can have them created without needing to write extra code to make those values each time.

2 Likes