Potential Backdoor or FE Bypass

Well, welcome to the fun zone.

Alright, step 1, check your plugins. You can insert any plugin you own and check the source like so:

local PluginIDHere = 13371337
local IS = game:GetService("InsertService")
local GrabAsset = IS:LoadAsset(PluginIDHere)
GrabAsset.Parent = workspace

Paste in the plugin ID and run this in the command line in an empty studio place. Do this for every plugin on everyone on your team. I’ve ran into plugins that insert backdoor scripts before, and while studio now warns you about it one may have slipped through.

Now, if your plugins aren’t the problem, here’s the real fun: You now have to verify every single script in your game. To do that, lets get EVERY SINGLE SCRIPT in one convenient location:

local QuarantineFolder = Instance.new("Folder",workspace)
QuarantineFolder.Name = "Every Single Script"
local EverySingleObject = game:GetDescendants()
for _, v in pairs(EverySingleObject ) do
pcall(function()
if v:IsA("BaseScript") then
local c = v:Clone()
c.Name = v:GetFullName()
c.Parent = QuarantineFolder
end
end)
end

This again must be ran in the command bar. It will extract every script except core scripts and allow you to to check all of them. Do not try to just use find functions. Manually inspect them. Malicious scripts are always devising new and interesting ways to avoid being caught by a simple search and they will abuse every tool in the box to do it.

Now, if you still haven’t found your script, well, oof. If there’s a backdoor, there is undoubtedly a script. So now we get into the seventh layer of hell: Scripts can hide in unions and still run. I have no idea if this has been completely patched yet, it absolutely used to be a thing, but such scripts will not get caught by the above segment of code I gave you.

In order to find union-concealed scripts you’ll have to grab every union and break it down bit by bit checking it. I sincerely hope you don’t have to do this as it is a titanic pain. Assuming you get to this stage, here is another segment of code for getting all of your unions:

local QuarantineFolder = Instance.new("Folder",workspace)
QuarantineFolder.Name = "Every Single Union"
local EverySingleObject = game:GetDescendants()
for _, v in pairs(EverySingleObject ) do
pcall(function()
if v:IsA("UnionOperation") or v:IsA("NegateOperation") then
local c = v:Clone()
c.Name = v:GetFullName()
c.Parent = QuarantineFolder
end
end)
end

If you for some reason have not found your backdoor after going through all of the above, then the most likely cause is your scripter cannot be trusted and I highly advise you get someone else to help you verify.

5 Likes

Alright! I think we found the issue, if not the specific issue we definitely found an issue.

Found this bugger inside an old, defunct walk sounds script that we forgot to remove when we made our new system. Unprotected client side remote.
unknown55

4 Likes

We just did, thank you! It was a r.Parent = nil inside an old walk sounds script that was being fired from the client.

Somewhat unrelated, but any scripter worth their salt should be leaving comments in their code telling others why that code is there and what it intends to do. It will save you significant pain if you ever get another scripter, new scripters, or if your scripter(s) have to go back to a script they’ve long forgotten.

2 Likes

The script was an old free model that hadn’t been removed. All of our devs leave comments.

At any time Roblox can stop giving a good amount of money, games can die as well, so it isn’t recommended to just do 1 game

2 Likes