Can’t wait for this roll out fully. it will help my custom command bar and admin system be a lot secure.
it would be nice to have a this as call so we can run code strings using it. but none the less a great addition love it.
I’ve run into what I assume to be an incredibly bizarre bug where adding a yielding loop (even in a spawned thread) will result in the script losing capabilities. I made a little reproduction file to create this bug.
ScriptCapabilitiesRepro.rbxl (54.4 KB)
For context why I am doing this: I’m making a system where you are able to import sandboxed mods, these sandboxed mods can interact with the main “Mod” environment which is not sandboxed (only provides specific functions), this all works up until I have anything that yields, as me trying to interact with the “Mod” environment results in it being sandboxed for some reason.
This doesn’t work:
Yet this does:
I’d be willing to provide my demo in DMs if needed for another repro, but I don’t want to share that file publicly.
This is awesome, pretty much exactly what I was hoping it would be at a basic level. I was a little worried early on in development about this feature because it looked a lot more limited than this at first, but I’m excited to see where it goes. I have lots of notes from my own experiences with sandboxing on Roblox.
Potentially unforseen challenges
I’m hoping at least some of this is already going to be addressed, but these are challenges that I have personally had to overcome with script sandboxing prior to this feature that are essential to my use cases.
- Text filtering (see section below)
- Permanent privileged functions
- While a function can be passed that temporarily has higher privileges, no self-respecting library developer is going to use bindables (sorry to any bindable-loving Roblox engineers, but, bindables are clunky and painful)
- I would propose providing a privileged API (or function attribute) that tells Roblox that a function’s privileges should be preserved when passed to lower level user code.
- This allows for a low level ‘kernel’ API to be written, instead of needing to use bindables, which ime have lots and lots (and lots) of overhead, and impose unwanted restrictions, points of failure, and add lots of boilerplate.
- A way to run arbitrary client code is currently missing. Ideally a way to ‘build’ new
Script
s andLocalScript
s from a piece of source code would be preferred.- Relevant, I noticed that the
Source
property of scripts lost its security level, but reads/writes to source are disallowed still. I have to wonder if this is already planned in some capacity.
- Relevant, I noticed that the
- There doesn’t appear to be a way to limit execution time, meaning there is nothing stopping a script with no capabilities at all from freezing or crashing the server. A basic version of this is definitely needed but I also have a whole wishlist of relevant stuff that’ll probably never be added but are still core to many of my use cases:
- I’d love to see something that would allow me to poll the total elapsed CPU time a script has used.
- Ideally this would not be an error, but instead would pause code at a sensible point until it’s given more ‘gas,’ or in non-yieldable threads kill the code if it runs for too long past the deadline (WoS allows for an additional 10 milliseconds)
- This has to be robust against spawned threads and should be local to the sandbox container or script
- I would expect that if sandboxed code calls a higher privileged function that was passed to it, the time would still show up when polled. ‘Discounting’ this time isn’t hard to implement manually by simply polling CPU usage during the execution of the function and crediting the script with more ‘gas,’ leaving the choice up to developers on how to handle the CPU usage of game code vs user code.
- The above is essentially how Waste of Space handles
Microcontrollers
, every 1Power
resource is converted to 1 ms of CPU time. Scripts are reset to 100 ms of ‘gas’ every game tick (which is currently once per second in WoS)- When a script runs out of ‘gas’ (the game will inject points to poll at into user code and does so in its APIs) it pauses if possible, otherwise it is offered up to 10 milliseconds to finish up with the unyieldable thread and escape to a yieldable point or be terminated.
Text Filtering
A way to filter text displayed by sandboxed code is required, or some guidelines around how inappropriate user generated content should be handled.
- WoS is an excellent test of what happens in-practice when users are subject to filtering for their UGC. Every piece of text outputted by a
Microcontroller
I treat equivalent to input text submitted by the user. I filter this text each time it is assigned. - Unfortunately, because Roblox’s filter is ‘contextual,’ when user code assigns many elements this usually results in almost everything being unconditionally filtered by Roblox regardless of the intensity of filtering on the user’s account. Not to mention, numbers are almost always excessively filtered to the point that it is nearly impossible for users to do what they want to do without the filter getting in the way.
-
RichText
is effectively not able to be filtered. There are no gaurantees that any old XML parser implementation would parse edge cases the same as Roblox’s parser, meaning that it is unsafe to attempt to allow tags inside ofRichText
to be unfiltered. This is sort of its own separate issue, but, it’s still relevant to why the filter is imo far too limiting for user code.
All of this makes most ‘informational’ builds in WoS almost useless in most cases. This has unfortunately driven some players to attempt to circumvent the filtering mechanics that the game imposes through a bunch of different methods. While we moderate against filter bypasses unconditionally, it creates a ton of friction between moderation and players who just want their (incredibly cool) stuff to work.
- So far, in the handful of cases that we have observed over the past couple of years, I have not yet observed an example of inappropriate behaviour involving filter bypasses yet (it’s way too much effort). However, I want better filtering tools & guidelines for user code.
- I would propose that Roblox allow a user ID to be assigned to code that runs in a sandboxed container, and that Roblox handles text filtering automatically.
- When code assigns text that’ll be visible, e.g. on a
TextLabel
, Roblox should filter this text when displaying it to other users as Roblox deems appropriate. When displayed the ‘owner’ user it should use more relaxed filtering, or disable filtering outright. - A prompt method that developers should call before executing a user’s code could allow Roblox to display guidelines around what the user is allowed to do.
- A copy of this prompt available to developers and game moderators would allow consistency around moderation regarding user code and what they display. This way, games can moderate, and players writing code can have flexibility.
- When code assigns text that’ll be visible, e.g. on a
+1 this. Can we please just have a native RBXScriptSignal
constructor at this point, bindables do a load of nasty stuff to tables to make them cross-vm compatible, but it would be nice to have a signal that stays enclosed in a single VM.
I’d totally love this. A way to natively create some kind of signal object that mimics what a lot of the existing signal libraries do would be an opportunity for performance improvements, and would be super convenient.
This, plus the ability to permanently preserve permissions on some privileged functions would complete the full set of things you’d need to conveniently write a ‘kernel’ API of some kind for sandboxed code to use.
The client hasn’t shipped with a compiler for close to a decade at this point and I don’t imagine that’ll change. It’s a security measure and cuts down on the size of the client to boot.
The change to Script.Source
is actually just related to the OpenCloud Luau execution beta. I wouldn’t expect Script sources to be accessible to normal scripts ever, personally.
This is great, but there’s a way of making it better.
Could we maybe get another way of executing code without loadstring? Would be cool if there was a function that can be ran both on server and client but with the capabilities option and some other options like custom globals, block certain services, etc.
Basically a customizable VM
I don’t believe there will ever be an “end of exploits”, but this will do quite a bit to deter malicious people from inserting scripts with bad behavior into toolbox models.
You can create ur own vm and compiler
This feature has nothing to do with exploits
I mean it works, but is always terrible in terms of performance. I would love if loadstring was possible on client because a game im working on is gonna have native modding apis & in some cases i need it to be as fast as regular roblox bytecode.
I dont think we need a compiler on the client. All thats needed is for the server to compile the bytecode instead and send that to client. This would also allow for CRAZY anticheat solutions.
This announcement is quite a reminder of how much I haven’t kept up with Roblox announcements for a while… My entire thought reading this was “wait, they’re doing this after all the loadstring fiascos back in like 2011? When did they change they re-enable it and/or introduce a new system for arbitrary code execution such that they’d even have a use case for this?”
It sounds cool, I guess, but not something I’d personally have any use case for.
This is a W update I can’t wait to fully grasp it’s use-case
spamming notifications now eh
I’m not saying it does, I’m pointing out, to the people who are saying it might put an end to exploits, how it won’t actually affect anything.
Experiences such as Build Island would greatly benefit from users being able to import their creations into the experience out of Roblox Studio, but this capability has been heavily restricted due to security concerns.
Now that we are getting fine-grain control over script permissions, when can we expect to see a relaxation of InsertService restrictions?
actually amazing feature
if only we could do this but for game client features as like a select to disable
The server compiles LocalScript
source, so, this isn’t really relevant to what I’m asking for which is just a way to programmatically build new scripts on the server.