Scary part is if you’re in a teamcreate and one person has the plugin - nobody knows.
The only thing I want to know, is why in the world is the CommandBar below the Plugin security identity?
I’ll look into writing a plugin for this as I think a few of my places are infected by it.
Security identities on the old Roblox wiki are outdated.
On the good side, support for private modules is being discontinued, so any infected assets will need to insert raw code to be able to function as intended and flushing out the culprit may not be as difficult. On the other hand however, the very fact that something can be inserted in this manner is concerning: especially when the only way to remove it is not easily accessible or understandable by all developers.
People go to some lengths to get a cheap kick, don’t they?
I had mentioned this in the post. When I just looked up the list I did notice that the security context page is not official. (It’s on a user’s self-created page by Anaminus) though creating a plugin to clean the infection was my first thought as well. Unfortunately I hit the same access level insufficient error that you did which is what prompted the creation of this post.
Oh, my apologies.
I tend to skip over large paragraphs of text, skimming through them. It’s a habit I’ve gotten into over the years, and is something I should get out of probably.
I’ve decided to go ahead and take a closer look at this.
Turns out, you can actually get a list of all Instances in any given game that require an unusual identity to access using pcall and GetDescendants. That’s not very useful on its own, but you can actually use Selection::Set to get all of those item selected (or any list of them). You can then just delete them like you would any other selected items. I wouldn’t recommend doing this for all of them because this list includes the descendants of CorePackages, which should really not be tampered with, but if something has a conspicuous name, I would check it out.
In this instance (I’m using a modified ReflectionMetadata to let me better mess around with this), the names are very suspicious and could easily be removed with this method.
That being said, all it would take is naming it something seemingly normal like
Value and this method would fail without a visual representation.
My recommendation would be to make it so anything that isn’t supposed to be there makes the service show up in Explorer regardless of what it is. That would solve this problem now and forever.
In the meantime, here’s a convenient plugin I made to just select things that aren’t meant to be there so they can be more closely inspected (and deleted) in the Properties menu. It’s relatively simple but it should work to identify and clean up stuff like this.
EDIT: There are errors that pop up when you select something like this but they’re from other plugins or built-in plugins so there’s not much I can do about them.
you’re a genius. Thank you!
Oh my, can’t believe I didn’t know about GetDescendants until this! Thank you for sharing. Using this information and a few hacky methods I was able to create a plugin for the automated detection and removal of this infection (as well as any script hiding in a protected locations or known infections located in the game.) The plugin will also allow you to choose to “Store” the infections in a new folder in ServerStorage that it will name “Infections” so you can view the scripts it detected as infections if you’d like.
https://www.roblox.com/library/2670956620/Hidden-Infection-Script-Detector for anyone who wants to use it.
(This plugin uses 1 require so I can easily update the known infection source excerpt string table that the plugin uses to scan scripts and check if they are infection scripts or not. This module is located here: https://www.roblox.com/library/2682779959/Hidden-Script-Scanner-Known-Infections-Table)
Oh jeez. I may or may not have completely forgotten about Insert, because, well, that’s not something you think about… Ever. Shout out to Roblox for unintentionally leaving us the tools we need to get the job done.
My initial worry was that now that we’ve called attention to this method it could be used maliciously by doing something like inserting the CoreGui into the workspace, but Insert is actually restricted already so it works in our favor! Please no patch Roblox! We mean well!
Incidentally, if you’re worried about a property being named ‘PropertyThatDoesNotExistPlz’ existing at any point in the future (I cannot possibly imagine you are) you can get the Classname of an Instance by checking the error that shows up when you call it with no arguments. Apparently calling an Instance is a thing because it actually casts a proper and unique error?
The fact that the infected plugin was disguised as a simple class converter is really worrying. I could have easily fallen for that.
I’m really not liking having to fear installing plugins (or even updating my current ones) because they might have backdoors I don’t know about.
here’s the… actual plugin if anyone is interested
not sure how to get that one taken down lol
Also a quick note, you should check if you’re in studio to run this because it currently sends an error whenever you’re on a client.
I already built in a Selection service fallback for just in case the InsertService method gets patched for this reason. Also in reply to your next post I’m pushing an update now for this, thanks for letting me know!
It would be nice if you could hook this up to #learning-resources:community-tutorials-resources for public exposure, since infected assets affect many developers, evidently.
A word of caution though: you should not be using a require module, even if the source code is public, because such support is being discontinued in no more than 3 months. Have the module placed internally in the plugin and instead prompt the user if the plugin is outdated and to go update it. When you update a plugin, people will be able to bring their installation up to speed and Studio will automatically refresh the toolbar to allow the updated plugin to commence its functions.
I’ll probably do that. (Update: Done, link to this post is here.)
As for the caution; That’s likely why I built in support for require failure to fallback to a local version of the table. Also to my knowledge the support is only removed for closed-source modules. Meaning as long as I leave it public it should be fine. (Which I intended to do anyways.)
We are investigating what we can do to resolve this issue.
A temporary patch would be to not allow the engine to execute scripts inside of “Backpack” instances that aren’t parented to a player. (This is an engine bug that the exploit creator is abusing to make the scripts execute in odd/hidden locations.)
Note: I’m unsure if “PlayerGui” instances will have the same effect but if “Backpack” instances do then I assume it will too.
There are a couple things we are looking at:
- Only executing scripts inside Backpacks/PlayerGuis if those objects are parented to a Player
- Preventing plugins and other scripts from parenting objects to CSGDictionaryService and other locked/hidden services
Separately we are going to add an optional setting to see everything in the DataModel, so power users will be able to see everything that goes on.
Is there any reason that any of these services are ‘super-RobloxLocked’ (as in, inaccessible to plugins)? None of them have any special API attached to them (and even if they did, they would have a separate security flag on them) and it seems to just be creating this sort of vulnerability without any gain from an outside perspective.
We did not intend for these services to be accessible to developers, e.g. CSGDictionaryService is for holding CSG data. It is possible that we will someday remove CSGDictionaryService so we did not want developers to start storing objects within it.