PSA: Enabling LoadStringEnabled doesn't instantly jeopardise your games

Often within the Scripting Support categories, I’ve taken notice to a lot of responses informing you that you need to disable LoadStringEnabled otherwise your game is up for exploiter attacks or some kind of other nonsense. The Game Security article to which is mentioned in the LoadStringEnabled warning doesn’t do much of a good job explaining the potential risks of it either.

Due to all these responses, misconceptions and lack of information, I’d like to respond semi-decisively to the debacle regarding LoadStringEnabled:

Enabling LoadStringEnabled does not instantly jeopardise your game's security.

Read the warning message very carefully. It is displayed before you enable LoadStringEnabled to inform you that there can be consequences for using it, especially if your game’s structure is poor.

image

Activating the LoadStringEnabled property might make your game vulnerable to exploits.

If you have any reason to be arbitrarily running code from the server with the global loadstring(s) without a custom interpreter, I won’t question your use case - feel free to enable it. That being said, don’t let answers without detailed explanations or the warning throw you off and don’t let this PSA drop your guard either. Poor game structures with LoadStringEnabled put you at great risk for exploits.

The typical recommendation is that you don’t enable this, as there are rare to no cases in which you actually need to run arbitrary code independent from the game structure you coded from Studio. In the case that you do need this, custom interpreters and sandboxing techniques are available and should be used to “minimise” risk while keeping the feature enabled.


Thought I’d share. I have absolutely no knowledge on VMs, interpreters or anything technical about Lua, so if there’s feedback or something that I’ve gotten wrong or missed, please feel free to point it out to me and I’ll make sure to incorporate the feedback accordingly.

Happy developing and remember to practice safe coding when it comes to client-server interaction. You don’t want exploited clients taking advantage of vulnerabilities in your game.

35 Likes

I’ll add: A common misuse is interpreting equations or calculations. Don’t do this with loadstring; opt to use an algorithm built for the job so you avoid arbitrary code execution exploits. See the shunting yard algorithm for an example - https://en.m.wikipedia.org/wiki/Shunting-yard_algorithm

8 Likes

If you explained how loadstring works and why that makes it safe/unsafe this PSA would be even more helpful.

3 Likes

Loadstring will allow you to execute strings as if they were code.

Users can send strings from client to server if you make use of RemoteFunctions. If any of those strings can make their way to some function where they can be executed as code, a client can:

  1. Give themselves free stuff
  2. Wipe or corrupt your data stores.
  3. Give themselves all the coveted player points.
  4. Probably leak all your server-side scripts (which are typically unreadable by clients).

Basically, this is a terrible place to find yourself, as a developer.


That said, if you’re at least somewhat conscious of what kinds of strings you’re passing to loadstring, it’s not too challenging to avoid this risk.

5 Likes

This is a big doubt; the server scripts executing loadstring are still subject to all the normal server script limitations, such as lack of script.Source access.

(Not to say it’s impossible through some other external APIs such as the half-broken place save API.)

4 Likes

Alright, fair. I’ll cross it out.

1 Like

This makes sense. I feel secure using loadstring as long as I know exactly where I’m getting the code from. For example, to run code stored in StringValues which that cannot be by any means changed by clients.

There are other powerful code execution methods to be careful about. For example, require(assetid), which allows executing any free ModuleScript from the library, effectively making it a more tedious brother to loadstring, but it can’t be disabled like with loadstring.

Whatever you do, still sanitize the data you get from clients before doing anything else with it.

2 Likes

I’d like to share my usage and experience with loadstring to give others a better understanding of it.

One of the most important things in Lua Learning is the ability to run code as you learn about it. Interactive learning really helps solidify the knowledge.

This uses loadstring.
I’ll admit, I was certainly worried about it at first.

I spent a good few months working on a sandbox system for safely running code, and so far I’ve had no issues.

My sandbox was based on two golden rules:

  • Whitelist, not Blacklist.

This means that instead of restricting what they can’t access, give what they can access. If you blacklist, you’re bound to forget something crucial and someone will find a way to abuse it. If you whitelist, forgetting just means you’'ll get a bug report and then you add to the list.

  • Client has no role.

Seems obvious, but worth saying anyway.
The client does nothing but send a string (the code) through a remote event. Everything else is handled by the server. The code is parsed, modified if needed (inf loop protection, inf yielding, mem usage limits, cpu time limits, etc), and then run in a carefully sandboxed (and monitored) environment. The client is told what outputs occurred via remote events, and the client displays those in a GUI. All of the code running and protection is very exclusively server sided.

This is an over-simplification, but it sums it up pretty well. The core of the sandbox is built around those principles. Most of the rest is very specific to my use case of seeing if the code passed the lesson.

The game has had millions of visits, plenty of Front Page exposure, and the only thing naughty people have done was use external tools to spam one minor RemoteEvent that I forgot to secure (I fixed that :sweat_smile:)

Overall, if used correctly, loadstring is a powerful tool. It should be treated with caution, but as colbert has said, it’s not an instant vulnerability.

13 Likes

I’d rather use a virtual machine alternative that replicates loadstring’s function. It’s slow but so is loadstring itself. I generally never use loadstring or the VM unless I’m running portable code from a website or something

1 Like

Loadstring makes bad code vulnerable, it’s basically the same thing with poorly coded Remotes.

Any other use cases other than sandboxing code?

And is there a reason why this isn’t enabled for Client side usage?, I can’t see how it’s a problem, Exploiters can already execute code without using loadstring()

Incorrect; loadstring functions run on the same VM as the other Lua scripts, so the overhead of a Lua-in-Lua VM is not present and it should run about as fast as your other scripts.

3 Likes

Roblox has removed the compiler from the client. Without it, you cannot really use loadstring.
The idea is, if loadstring worked on the client, then exploit creators would be able to make their exploits simply call loadstring() with code they want executed. It would make the process so easy that almost anyone with some knowledge would be able to make their own exploit.

You know how right now you need to recreate the lua vm (cough rerubi) in order to execute code from a string on the client? Well, imagine exploits have to do something similar, except in the C++ land full of taps and checks.
It’s better to have only a few people that can do that, rather than almost everyone, isn’t it?

1 Like

Keep in mind I know nothing about loadstring

EDIT

Look at the post above, mk thanks.

If client-side usage isn’t enabled, that means loadstring() is only able to be fired from the server (obviously), which logically means it would always modify the server (also obvious). This means that there is a chance that, since client-side usage isn’t enabled, that loadstring() was only made to directly modify the server… which doesn’t make sense but if someone thinks I’m on to something then hey, be free to take my hypothesis and expand it to something that makes sense.

Yes but in a perfect world that we don’t live in, honestly anyone even a yokel can find an Exploit to use without any effort, so disabling Loadstring for Client-Side is doing a pretty terrible job from what I can see.

Not every exploit incorporates what’s called a “Script Executor” - I don’t know the technical term, just exploiters call them that or “Level 7s”. The majority of free exploits are “Level 4s” or below, with an occasional level 7 coming out once for a preview, but when they get patched it goes paid. Level 4s only allow usage of certain commands (basically mini admin commands), such as “kill player”.

Most level 7s are paid, and the ones that are free would probably have limited features to the executor (Full lua executors and other stuff, I don’t understand the differences between this though).

Therefore, if you did enable Loadstring for Client-Side, the level 4s would be able to all incorporate Loadstring in order to replicate the effect of level 7s. Most of the 15- community wouldn’t bother paying for an exploit on a “lego game” (as they would put it), therefore they would turn to the free exploits which would lack executors (unless a free one had conveniently came out that week). If the level 4s had access to loadstring, whilst they’d probably look trash as executors since they don’t usually come with custom built UIs and just use things like command prompt for appearance, then this part of the community would be able to execute scripts without effort, as you mentioned, however that is in the case that loadstring becomes client-side.

I don’t know too much of the details since, well, I’m not an exploiter, nor do I know anything about how Roblox handles loadstring, but I hope this helps clarify some things about free vs paid exploits.

1 Like

That’s a really interesting use of loadstring, I like the idea of whitelist not blacklist

@superhudhayfa
as far as I know exploiters can’t simply run code directly on to the server by themselves, that’s not what level 5/level 7 means. The reason why you sometimes see exploiters making changes to the server is because of hidden backdoors brought in to the game through malicious plugins, malicious developers, etc. With loadstring enabled, exploiters can send code data to this backdoor and have it directly executed on the server! This is why loadstring can be dangerous; if the server is directly executing code sent from clients.

1 Like

I don’t recall writing anything about saying that exploiters have the ability to write code to the server. I’ll re-read everything I said and edit this appropriately to avoid misconceptions.


Sorry, this is a fault in how I wrote the post. I didn't mean that level 7s have the ability to execute code to the server, just that they had the ability to execute code, through whatever means, that edits the client - I don't know the intricacies of how this works. With Loadstring enabled on the client, assuming that client-side usage would only affect the client and server-side usage would only affect the server, level 4s would be able to replicate the effect of level 7s. If loadstring enabled on the client allowed direct access to the server, then that's a different matter.

I’m being quiet ambiguous since I don’t know the whole details, so if you can’t understand what I mean then… :man_shrugging:

I think you greatly misunderstand what “disable loadstring on the client” means. It means the client is not compiled with a Lua compiler in its binary at all. Without a Lua compiler, people are forced to go through dozens of hoops just to get proper Lua structures formed in memory as opposed to calling a function that does it all for them.

Loadstring on the client is simply a huge security hole.

@superhudhayfa I wrote this on the topic which has more info on that stuff Exploiting Explained

3 Likes

I see now that you have pointed it out, I didn’t understand that part before, I don’t have a good understanding of how the compiler works and all, as I am wondering if it doesn’t have a complier how can it run Local Scripts? But I’ll leave it there as this is off topic and I can research on my own.

Thanks for the insight



You shouldn’t use loadstring for the exact same reason JavaScript developers are heavily warned against using eval: You could open up an opportunity for a XSS attack.

Also, if you have to use loadstring, then that means you’ve designed your system poorly. You should never have to execute arbitrary strings as code in your system. Never in my 11 years of programming have I had to do this.

So I agree with OP’s points that a lot of people misunderstand why it’s considered a risk, but I would still heavily recommend never using it except for experimental projects.

2 Likes