In September 2013, we launched a service to compile Lua files for your MTA servers, hosted within our web network - https://luac.multitheftauto.com . Currently, the service offers some basic encryption abilities and some (admittedly imperfect) protection to prevent decompilation, and an API so that users can compile scripts as simply as possible.
Over time this service has been gently encouraged in MTA Server debug warnings until it has become fully enforced. Now, all compiled scripts are required to go through this service or they will not run on your MTA Server. We've had no choice but to keep quiet on the motivations behind this process, but this post seeks to clarify the circumstances for which this had to happen. We can only apologize for the clear disruption this causes servers (particularly larger ones), but hope that you'll agree that when we say that we were backed into a corner.
Keeping our users safe
MTA is a complicated mod where we have multiple stakeholders that we have to consider. The main ones are hosting service providers, server owners, and our players. It's our job to ensure that all stakeholders are catered for, and crucially, they are kept safe. This is particularly a problem for players. We simply cannot trust server owners to always provide a safe environment for players - a scenario where a server owner baits players into joining to distribute viruses is unfortunately a reality that must be dealt with.
Enter Lua bytecode. For those unaware, the junk that you see when you open a compiled script is called "bytecode", so a compiled script or bytecode are more or less the same thing. Over 3 years ago, a lecture by Peter Cawley at the Lua Workshop 2011 presented a number of bytecode exploits in Lua 5.1 and 5.2. I actually spoke to some resident Lua experts over at Freenode who only reiterated concerns surrounding the use of bytecode in Lua. The consequences of such a discovery is clear: a booby-trapped script can be sent to unwitting players who have their systems exploited. Around the time luac.multitheftauto.com was launched, a proof of concept exploit was released - exploiting the Lua engine in the game Company of Heroes 2.
I can't recall exactly when we first became aware of the dangers of having bytecode enabled, but I think it was towards the end of 2012. We started taking serious consideration over the issue in early 2013. I actually contacted Peter regarding our options over this. After plenty of research we established a few possible ways to deal with the issue.
What our options were
1) Disable compiled scripts. This is the most obvious answer, and the best way to guarantee safety for our users. Researching how other software dealt with this exploit revealed that this was the best option. Now we get back to stakeholders: by doing this we guarantee the safety of our players and the future of the mod, but agitate all our server owners in the process.
2) Implement a way to detect malicious scripts. If the client and server had a built in way to detect the scripts that are malicious, then we could simply block those. Unfortunately, none of the team are experienced enough with Lua's intricacies to stand any chance at implementing this ourselves. A 3rd-party Lua verifier was actually released, but only for Lua 5.2. There are a number of issues with this. We don't support Lua 5.2 - so we'd have to spend time upgrading it in MTA. This might not sit nicely with things such as the then in-progress OOP implementation. The main issue is that there was no active development on the verifier, with the last commit being in September 2011. This is arguably fine for something that's 'finished', but after further indications that the author wasn't actively looking at bytecode issues, worries of a 'cat and mouse scenario' began to creep in. Even if we adopt this verifier, there's a chance more bytecode exploits are found - and when that happens we have to wait for an inactive project to be updated. On top of all of this, compiled scripts in Lua 5.1 aren't compatible in 5.2, which means everything would have to be recompiled anyway.
3) Make sure that all compiled scripts are safe. This third option is subtly different to (2). What if we can verify compiled scripts are safe by making sure the compiler is safe? If only a single compiler can be used, then no one could booby-trap their scripts. This would further require a way to prevent users from modifying scripts used by this compiler.
Initially, the consensus was to disable compiled scripts completely, and we had been discussing ways to replace the functionality of compiled scripts. Protecting scripts could be offered by some form of encryption - but we're not cryptographic experts and could never guarantee protection of scripts - in fact script protection was more of an idea and didn't really have a solid roadmap. It made me wonder whose responsibility it actually was to protect the content of scripts. Either way, all the existing compiled scripts would be rendered incompatible with a newly introduced encryption system.
I've already gone into detail over why option (2) proved to be impractical, which left our third option - providing our own compiler. By ensuring all scripts are compiled by https://luac.multitheftauto.com, we know for sure that they are legitimate and have nothing harmful in them. So, why not distribute an offline compiler? We also have to prevent against script tampering - i.e. scripts compiled with our "official compiler" then modified afterwards. We prevent this using code-signing technology - the same certification system we use to sign the MTA client itself. In layman's terms, we put an MTA "seal of approval" so if someone tampers with the MTA client executable, the seal is damaged and things break. The same principle applies to scripts compiled on https://luac.multitheftauto.com. It's simply not possible for code-signing to happen offline since we're the only ones who can stamp the 'seal'.
Hosting the compiler gave us the opportunity to implement some extra features that server owners may benefit from, such as anti-decompile, and some basic encryption. It also opens doors in future - we can potentially take further action against some of our shadier scripting community. I'd also like to point out all this research and the final decision happened over several months of deliberation - how we stop the exploit, when we can implement it, and how we tell the community about it.
Why we remained silent
This was an extremely delicate situation. If this post had been made back in 2013, we would have effectively announced to the world that there's an security hole sitting in MTA waiting to be exploited. Equally, by not coming clean we would basically be forcing server owners to pass scripts through our servers and not explain why. Overall, we felt the safest choice was settling for the latter, despite issues we might face. We chose to make our online compiler, but phase it in over the period of almost a year.
Before now, I've responded to angry server owners by pointing out the benefits of things like the script encryption, but the underlying motivation has always been about bytecode exploits. It's inevitable that things like anti-decompile are being cracked, but there are now new avenues to enhance protection to make things better for server owners.
We announce this now because we feel our players are largely safe. To keep it this way, we urge anyone who's found an exploit or even got around our compilation to check our Security bounty scheme.
What does luac.multitheftauto.com actually do?
There are various rumours over what luac.multitheftauto.com actually does, and what we do with your scripts. The answer is simple: you send a script to the server. The server then puts it through a standard Lua 5.1 compiler. It then signs the script. If you opted for encryption, the script is encrypted using a private key. Then it gives it back to you. Nothing is stored, and there's not even anything automated to read the code in the scripts.
Hopefully everything I've said already makes it clear that there's no reason for anything else to happen.
We have no interest in stealing your scripts
Which leads me to an important point: we don't want to steal your scripts. We don't care for drama or politics, only for our user base. There is no motivation for any of us to steal your scripts. This should be self-explanatory - it makes no sense for us to introduce a way to hurt the users of our software.
"But what if you wanted to sell the scripts for your personal gain, and probably world dominance?" I hear you cry. I say this: if we wanted to steal your scripts, don't you think we would have come up with a much smarter way than to invite people onto our website to upload them? We're developing a piece of software that's designed to interact with servers to send and receive files. You do the math.
Other concerns that are commonly raised is that server owners don't want to risk their scripts being exposed in case our server is hacked. Once again, for reasons outlined above, we don't store your scripts. That's a waste of our webspace. We only care for compiling them, and making sure they're sane. Nothing is stored on our servers.
Another one is that by making scripts go through us, we're making scripters rely on the indefinite existence of https://luac.multitheftauto.com . What if we can't afford the rent and the website suddenly goes down? This is a valid point, but for reasons stated above we have no choice but to compile the scripts ourselves, on our web server. Moreover, the server browser master list and other services are already hosted by us - so some form of dependence on MTA's services is uncontrollable.
Will things ever go back to how they were?
As you can see, we spent a long time figuring out how to deal with this problem. It's unlikely things can ever go back to traditional offline compiling. But keep in mind the reasons why this was introduced. If you have experience or possible avenues that could be explored, we're always open to suggestions (or even someone implementing it themselves). At the end of the day, we try to make sure all our users are happy. So if there is a Option (4) out there, it's not something that's already ruled out. In the meantime, we've tried to bridge the gap by offering an API, and some members of the community have developed tools to help.
Thanks for reading