Improve the Module System to Have Additional Security

development
scripting
modulescript
security

#1

As a Roblox developer, it is currently impossible to publish modules that are both trustworthy and secure. The current Module system allows for the use of published modules that are copylocked by their creator. As these modules are private, their source code is obviously inaccessible to everyone but the developer. As a result, there are lasting worries about using private modules because there is no way to verify what they are doing. There is also a very real worry that a popular free model could inject malicious code into many games because younger or less experienced developers (i.e. the main users of free models) often do not screen models they insert, or are not aware of the security hole a private module creates.

Due to the issues with private modules, people have been understandably hesitant about the entire idea of them. However, these modules do have legitimate uses and reasons for being private such as preserving an IP; selling a product; or even just hiding a url, as was addressed in a recent thread. Because of this, it seems prudent and necessary to update the security on private modules, as they are most likely not going away.

Additional security on module scripts could take a few forms. The most effective and preferred way would be to have a prompt when inserting a something with a published module used within it that would contain a list of permissions that said module needed to function. Think similar to the Android app permission system, where apps are published and have metadata in them that indicates what permission they require (and if they’re not granted that permission, they can’t use it):

The obvious problem with that is that it wouldn’t be supported by modules that are older, and that could break a few things. In a perfect world, permissions would automatically detected from the code of modules, but that is simply not practical. It also would require a lot of restructuring and make the module system far heftier than it as the moment.

A second option would be to have a prompt on insertion that informed the studio user who published a module and provided a description for it. That has the benefit of not hurting legacy modules, though it relies upon users to be honest and to use common sense – something that’s often lacking in people.

A third option is to simply disable private modules from being published to free models. Of all of these, this is the most blunt, but it would work to protect people from malicious modules. It does have the downside of eliminating a few uses of private modules, but there’s a serious argument to be made that private modules do not belong in free models anyways. It could also break a few previously published models.

EDIT: As Reinitialized has brought up in his reply, another fix for this would be to have a checkbox option such as AllowThirdPartyPrivateModules in the vein of HttpEnabled or LoadstringEnabled.

Crazyman32 also brought up the point that version control over module scripts would be good as well because arbitrarily updated and executed code poses a big risk for actual use of module scripts.

Whatever ends up happening, as long as it improves the overall security for end-users against malicious modules, I absolutely support it. Something has to be done about it.

As a developer, my life would not change much regardless of what happens here (if anything is implemented or if nothing is) because I mostly use my own code for things. However, the effect this would have on free model users and on those who publish/sell modules should be reason enough to do something with it. It would also help bring modules into a more modern age.


Removing Support for Third Party Closed Source Modules
Removing Support for Third Party Closed Source Modules
Removing Support for Third Party Closed Source Modules
#2

Ooorrrr … Give us a check box such as AllowThirdPartyPrivateModules which is disabled by default, acting like LoadstringEnabled. This effectively protects the users and would give a similar prompt to enabling loadstring regarding the risks of Private Modules.


#3

Another issue is that we don’t have any versioning. If you use a private module, the author can change the module at any given time.

If that doesn’t frighten you, then I don’t know what will. Using private modules from other people is giving them the power to run arbitrary code in your place that could change at any time. Not only is this bad in terms of stability and compatibility, but it’s a huge security issue.

If we could force the ‘require’ to link to a specific version, this would be really helpful for developers.

In the mean-time, I would avoid ever using private modules. There are many other issues too that I could write about, but will hold off from doing so here.


#4

Here are my thoughts on the matter.

Requiring

Private assets should not be requirable or loadable in any way by unauthorized parties. That is, the content of my private models should never be visible to arbitrary game servers.

A requirable asset (henceforth referred to as a “Module”) should be indicated by either an option on the asset, or with some sort of new “Module” asset type.

A Module can be public or private. Public Modules can be required in Studio, and the content can be viewed. On a private Module, all requirements are taken to ensure that its content is not made visible, including only allowing it to be required in live game servers.

A user should be able to require a particular version of a Module. This could be done with the asset version ID, or a more convenient asset ID + version number. Specifying no version selects the latest.

Authorization

It should be possible for the owner of a Module to select which users/groups/games have access to it, with fine-grained detail.

Aside: It might be interesting to extend this to apply to all assets.

Permissions

Required Modules should run in a restrictable environment, with access limited to APIs selected by the user.

It would be convenient to have sets of permissions that apply on multiple layers. For example, user/group applies to all Modules within all games of a user/group, game applies to all Modules within a game, and module applies to a specific Module.

Private Modules should be isolated from other environments. It may be effective for Modules to run in a separate identity, which is complemented with a new security context, applied to sensitive APIs like HttpService, AssetService, and DataStores. Note that this would require the use of patterns like BindableFunctions in order pass functions through identities.

A system that displays requested permissions and prompts the user to either allow or deny the Module is very limiting. The user must either risk allowing undesirable permissions, or avoid using the Module entirely. A better system allows the Module to query allowed permissions at runtime, and make decisions based on which APIs are available. This allows the Module to be used even with certain APIs disallowed.

Module Privacy

There’s also the reverse part of security to consider. It’s possible to reverse-engineer the behavior of a private Module by modifying the environment it runs in, or by passing dummy values with metamethods. Unless a Module is written with care, it can be possible to retrieve sensitive data, such as web endpoints or security keys.

This might be resolved by using a separate identity, as mentioned above. A hurdle to consider is that each Module would require its own isolated environment, which may be beyond the current capabilities of the security identities feature.

Other

This is great as an intermediate step, but it would have to be enabled by default to have any real effect. It should be possible to do the enabled-by-default-for-new-games trick to accommodate current users of private modules.


#5

Yea, I never thought about the possibility of private modules being used in this fashion, but this is definitely a security problem.

Not only that but it prohibits new users from learning things that could potentially help them. If a module is private and they never get the opportunity to tear it apart to see how it works, that would hurt their creativity and they would think coding is literally just writing require(42983715). I learned all my knowledge of functions, objects, and parameters by just looking at other people’s code. Not until I got to that level did I actually start looking at the wiki looking for new API’s and things of that nature. I think it’s important not to scare kids out of learning coding by presenting them with something confusing they’ll never see anywhere else.


#6

Bumping these suggestions in the actual Platform Feedback section so that hopefully another solution can be met rather than completely disabling private modules.


#7

I think an interesting concept that I haven’t seen anyone on Roblox do before is just offering modules or plugins with licenses. Selling code to other developers with legally binding contract on how it’s allowed to be used, and if you really don’t trust people you can just obfuscate code uniquely for each license you hand out so it’s easy to trace leaks back to the person who violated the agreement. And you can do all of this today because it’s not reliant on Roblox developing a system, you’re just using real world legal strategies like all other software development.