jmossr Posted Saturday at 10:56 AM Posted Saturday at 10:56 AM 2 hours ago, Actium said: I can confirm that this does indeed not work as advertised. Running the following code from DCS.openbeta/Scripts/Hooks return {net.dostring_in("mission", "return 1,2,3")} will yield the following return value: [ "1", true ] Maybe there's a mixup with a_do_script() available from the mission environment/zone? See the recently updated %DCS_INSTALL_DIR%/API/Sim_ControlAPI.html: The a_do_script() change is also part of the 2.9.18.12722 changelog. However, it is also broken, despite being the second attempt [1, 2]. This looks a lot like the old api/signature we had before local ret, success = net.dostring_in(env, lua)
Special K Posted Saturday at 12:20 PM Posted Saturday at 12:20 PM (edited) vor 18 Stunden schrieb Tippis: Your solution is unsafe and does the exact opposite of what this change is meant to accomplish. He? I don't think you're understanding the change mate. I told people to NOT open up everything but to create a file which works for their solution. I provided one which opens the minimum for server owners, mission and server, which in fact is very secure and not the issue for the casual user anyway. The problem lies at a different place. But if you know it better, I'm all ears how you would go with the scripts that use net.dostring_in() now. Edited Saturday at 12:27 PM by Special K
eekz Posted Saturday at 02:58 PM Posted Saturday at 02:58 PM (edited) Well... played with it a little bit. did net.dostring_in('export', return LoGetWorldObjects()) from mission's SSE hosted on the server. Returns empty string instead of a table. seems still can't call any custom functions declared in gui via net.dostring_in('gui', 'someCustomFunction()'), only net functions seem to work. return value will be [string "return someCustomFunction()"]:1: attempt to call global 'someCustomFunction' (a nil value) no matter how you declare it in gui script. can't really get the benefit of the change and how it supposed to work. maybe im stupid Edited Saturday at 03:14 PM by eekz 1 VIRPIL Controls Servers
kira_mikamy Posted Saturday at 03:53 PM Posted Saturday at 03:53 PM next time tell us that 1 second before patch, thanks. 3
Karlos Posted Saturday at 05:11 PM Posted Saturday at 05:11 PM (edited) As others have said, the lack of respect for the community is what's most disappointing. A timely warning would have been a great solution. We create missions, others offer their expertise to create scripts so our missions can improve, others offer their computers or servers to host the missions, mostly for free. I've been doing this since 2013 with FC2. I offer my servers, and with every release, we've always had to work on the server to ensure there are no errors and then patch things up so everything can work properly. We put our energy and time into the community, and no one pays us. I imagine you know this, or not? My servers are closed now because my missions aren't working! You sell the product, we create the quests, thanks also to the help of people like Grimes, Speed, Ciribob Cfrag, etc... who create and have created scripts to help quest administrators improve their servers and mission. Slmod doesn't work either. Edited Saturday at 05:17 PM by Karlos 5
eekz Posted Saturday at 05:14 PM Posted Saturday at 05:14 PM By the way, it's is mentioned in patchnotes that the ability to pass args and return values from mission scripting “a_do_script()” and “a_do_file()” was added. Can we have some basic example how to do that? Is it 2nd, 3rd args of the functiosn or? Not obvious 3 VIRPIL Controls Servers
Actium Posted Saturday at 07:56 PM Posted Saturday at 07:56 PM (edited) On 7/25/2025 at 10:53 AM, BIGNEWY said: No problem, the team are looking at the feedback and what has been affected in the community. @BIGNEWY As you are soliciting feedback, here's mine. Please forward this to your developers. I've reported an arbitrary code execution vulnerability, initially in December '24, which I presume may be related to this API change. Recently, I've also suggested a straightforward mitigation method that would incur far less collateral damage than the current approach. TL;DR The new net.dostring_in() security option is conceptually flawed: It only mitigates the vulnerability in a basic configuration, its configuration can be easily changed from privileged scripts (rendering it useless), and, most importantly, it cannot be configured to allow required, legitimate use of net.dostring_in(), while simultaneously preventing potential exploits. The changes cause a lot of collateral damage, while not fixing the root cause of the vulnerability. IMHO, this change should be reverted and ultimately substituted with a superior alternative. This alternative should be co-developed with community contributors that rely on the scripting API to find a proper solution. Inofficial Security Advisory On 7/22/2025 at 4:14 PM, BIGNEWY said: As net.dostring_in() is now even more powerful, security options had to be implemented to ensure that the API is only called between the intended secure zones. On 7/22/2025 at 4:14 PM, BIGNEWY said: We also warn that by using this API you will allow missions/scripts to do unsafe actions up to arbitrary code execution. What this fails to mention is that DCS versions from at least 2.9.10 (probably sooner) thru 2.9.17 are vulnerable to arbitrary code execution via specially crafted mission files. I'll responsibly refrain from divulging any further information. Suffice it to say that I figured out how to exploit the vulnerability from information that I gleaned from this forum, so the required knowledge is already out there. The exploit does not require the now added return value pass-thru of net.dostring_in(), which is apparently broken anyway. Beware of untrusted mission files in combination with exemplary autoexec.cfg files out there! As predicted by many previous posters, I've already seen a few autoexec.cfg incarnations with potentially unsafe settings. Anything that includes "scripting" in net.allow_unsafe_api is presumably dangerous. Kudos to ED for clearly pointing this out in %DCS_INSTALL_DIR%/API/Sim_ControlAPI.html: net.allow_unsafe_api = { "userhooks", -- will make the API visible in _$WRITE_DIR/Scripts/Hooks/*.lua_ scripts "scripting", -- enables the API in the mission scripting state. DANGEROUS!!! "gui", -- system hooks and GUI state } @BIGNEWY This very important detail is hidden away. I'd suggest to add it to your first post in this thread. Technical Background To comprehensively address the efficacy of the security option, I first have to outline my understanding of the technical background of net.dostring_in(). @Experts: Please correct me if I'm wrong with anything! DCS relies on multiple Lua interpreter instances to isolate different scripting zones/environments/namespaces from each other. They contain entirely separate global environments (_G variable). These are called lua_State in the Lua documentation and are also referred to as states in DCS' documentation. The states are isolated from each other, but some applications require to run code and get return values from other states. That is where net.dostring_in() comes in: Quote net.dostring_in(state, string) -> string OBSOLETE and UNSAFE!!! Executes a lua-string in a given internal lua-state and returns a string result This API is only allowed in the states listed in the local $WRITE_DIR/Config/autoexec.cfg: net.allow_unsafe_api = { "userhooks", -- will make the API visible in _$WRITE_DIR/Scripts/Hooks/*.lua_ scripts "scripting", -- enables the API in the mission scripting state. DANGEROUS!!! "gui", -- system hooks and GUI state } Only states with names listed in autoexec.cfg settings will be accessible as API targets: net.allow_dostring_in = { "mission", -- will allow executing net.dostring_in("scripting", "lua code") } NOTE: There's no need for net.dostring_in anymore. You can return values from a_do_script() mission scripting API directly: local a, b, c = a_do_script("return 1,2,3") AFAIK, the following Lua states exist: "config", "export", "gui", "mission", "server", "scripting" (new since DCS 2.9.18; separate from a_do_script()), and "userhooks" (new since DCS 2.9.18). Some of these states are trusted and privileged, e.g., "gui", "server", and "userhooks". These are allowed to read and write arbitrary files and call external programs, which is how SRS launches the client automatically on SRS-enabled servers. Other, unprivileged states run untrusted code from mission files, e.g., the "mission" state. Potentially dangerous Lua functions, e.g., for writing files and calling executables, are sanitized from these unprivileged states. @BIGNEWY What's the purpose of the new "scripting" state? It appears to be a separate Lua state from both "mission" and a_do_script(). Benefit / Efficacy The implemented security option restricts the use of net.dostring_in() within privileged, trusted Lua states, too. As these states already have access to privileged Lua functions, using net.dostring_in() to access a different state will not result in privilege escalation. Also, if the respective state can write files, it can modify autoexec.cfg and edit net.allow_* to change the security options to more permissible ones (after a game restart). Hence, attempting to restrict these privileged states is entirely useless. Unfortunately, that design choice has an unpleasant side effect: To permit the already privileged states to access all other states, implies permitting the non-privileged states to access all other states, too, because there's only one global net.allow_dostring_in setting shared between all source states (where net.dostring_in() is called from). A real-world example would be the need to let "userhooks" access "server" (e.g., Olympus) and let the mission scripting state ("scripting"?) access the "mission" (triggers) state, e.g., to access functions like a_unit_set_life_percentage(). That would result in the exploitable situation, where mission scripting can access the "server" state. The breaking changes do not fix the root cause of the vulnerability, which is the availability of potentially dangerous functions that allow unrestricted read/write file access and the execution of arbitrary programs. How to deal with these potentially dangerous functions should be the subject of a future discussion. Which missions/mods/scripts need them and how they could be made safe. Cost / Breakage Scripting in DCS is already not trivial due to the fragmented Lua states, requiring workarounds that rely on net.dostring_in("mission", ...) [1, 2] and a general lack of documentation. Incompatible API changes that break these workarounds frustrate the mission makers that desperately rely on them. The alleged obsolescence of net.dostring_in() (see above quote) adds to the feeling that the developers are not fully aware of what their API users actually need. There are many uses for net.dostring_in(), e.g., Olympus, Lua consoles, etc., for which a_do_script() is not an alternative. I'd highly recommend to discuss such drastic API changes with the community well in advance. Breaking changes must always be thoroughly studied and it is painfully obvious that these changes have not received the amount of thought they deserve. Conclusion The design of this new security option is fundametally flawed: It is inherently insecure, i.e., vulnerable to arbitrary code execution, when configured for standard use cases, e.g., Olympus + access to "mission" state from a_do_script(). It adds unnecessary complexity by restricting already privileged Lua states, where the availability of net.dostring_in() does not enable privilege escalation. Hence, this does not improve security. The security option configuration is not tamper-proof. Privileged Lua states can modify autoexec.cfg arbitrarily to bypass all previously configured restrictions after a DCS restart. This design issue renders the security option useless. Above issues illustrate how the security option design is ill-conceived. These issues alone are sufficient to revoke these changes and to restore the scripting system to the behavior of DCS 2.9.17. What makes matters worse, however, is the collateral damage in terms of API incompatibility, which breaks community content. Alternative To alternatively mitigate the arbitrary code execution vulnerability, while simultaneous permitting legitimate use of net.dostring_in() from mission scripting, the following wrapper function could be placed within %DCS_INSTALL_DIR%/Scripts/MissionScripting.lua: ---BEGIN-MISSION-SCRIPTING-EXPLOIT-MITIGATION--- -- insert this block into %DCS_INSTALL%/Scripts/MissionScripting.lua above: -- --Sanitize Mission Scripting environment -- mitigate arbitrary code execution vulnerability with a wrapper for -- `net.dostring_in()` that restricts its access to the "mission" Lua state. -- accessing the "mission" Lua state is required for some advanced scripting: -- * https://forum.dcs.world/topic/354648-add-setlife-function-to-lua-api/ -- * https://forum.dcs.world/topic/358877-lua-function-unitsetlife/ -- * https://forum.dcs.world/topic/371036-outpicturefor-lua-mission-scripting-functions/#findComment-5672179 -- this copies `net.dostring_in()` into a lexically scoped local variable and -- then overwrites the original function with a wrapper, which captures the -- local exclusively, because Lua is scoped lexically: -- https://www.lua.org/pil/6.1.html local _dostring_in = net.dostring_in function net.dostring_in(lua_state, code) if lua_state == "mission" then local _result, _success = _dostring_in("mission", code) return _result, _success else -- TODO: add error logging return "Invalid state name", false end end ---END-MISSION-SCRIPTING-EXPLOIT-MITIGATION--- Obviously, this is provided as is, without any warranty of any kind (as per the stipulations of the MIT license). You should know your code better than me to figure out whether this is safe or not. Regardless, I hope this helps make DCS safer, while keeping mission makers happy. Edited 7 hours ago by Actium 2
Kang Posted Saturday at 08:09 PM Posted Saturday at 08:09 PM 7 hours ago, Special K said: He? I don't think you're understanding the change mate. I told people to NOT open up everything but to create a file which works for their solution. I provided one which opens the minimum for server owners, mission and server, which in fact is very secure and not the issue for the casual user anyway. The problem lies at a different place. But if you know it better, I'm all ears how you would go with the scripts that use net.dostring_in() now. It isn't your file that is unsafe, mate. It is the fact that your solution is to just include a modified file with your mission, which most users will neither want to nor be able to question. Your autoexec file might be good, but will one I include be? 3
Tippis Posted 20 hours ago Posted 20 hours ago (edited) On 7/26/2025 at 2:20 PM, Special K said: He? I don't think you're understanding the change mate. They are quite easy to understand and you have described it fully. On 7/26/2025 at 2:20 PM, Special K said: I told people to NOT open up everything but to create a file which works for their solution. I provided one which opens the minimum …which is still more than it should be and which creates insecurities that didn't exist and shouldn't exist. It's that simple. This is a bad solution, implemented hastily with no warning and seemingly no testing of value. The number of things it breaks for no gain is ridiculous. The workarounds create bigger problems than what initially existed and does the exact opposite of what was intended with this whole idea. Hell, even the OP gives a big red warning sign. The reason I say that you didn't do any testing is because you've managed to break SLmod for a number of people — probably other common and crucial mods that are used all over the place. This should have been an immediate discovery and show-stopper. On 7/26/2025 at 2:20 PM, Special K said: But if you know it better, I'm all ears how you would go with the scripts that use net.dostring_in() now. I would suggest a two-step process: Hotfix-patch rollback. Do any of the things cfrag has suggested. Or see two posts above. This may seem drastic and contrary to how ED does anything, but trust me, the alterative is much much worse. That alternative would require them to, first thing tomorrow morning… At the top of the forums, the DCS website, the launcher, in the game main menu, and on every reddit, discord, and My Little Pony Online chatroom where they have any kind of social media presence, put out a warning sign in huge blinking letters that they have changed the security model in such a way that users may now be tricked into allowing remote code execution. In a very public post — not hidden away in this obscure “mission editor” corner of a forum that not many visit to begin with — document, in full, what the function does, how the different scopes work and what they affect, and under what circumstances each scope might allow for ACE. List and publicly endorse the minimalist exception rules for the 12 most common scenarios where you might want to allow dostring_in to work, from an end user perspective (eg if you want to use some of the products ED sells, or use userfiles of some kind), from a server perspective (how do you still allow common server mods to function, what are the caveats, how does it minimalisticly mesh with eg. shared moderation roles), from a coder perspective (what are the most common uses, what do these require in terms of exceptions, what are other more secure ways of doing the same thing). 36 cases in total, full documentation, full transparency of where, when, and how code (and in particular remote code) can be executed. Determine and clearly communicate which scopes and combinations should pretty much never be used because of what they open up. And in doing so, maybe just not allow that to begin with. Again, anything that creeps towards “remote…” should probably be stomped hard. Implement some kind of code signing so the end user can differentiate between trusted developers and random junk they find on the intenet. Congratulations, you are now Microsoft. Oh, it's just text files and there is no way to sign those…? You don't say… It's almost as if it has caused new problems. Implement a security tab in the game settings where this and related settings are made. Too many things are affected by this to just leave it as an obscure text file code injection — that just leaves option the ability to trick people into putting harmful code in there. If kept, the model need to be extended to not just be “these scopes are allowed use; these scopes are allowed access” but rather make it a proper model where you can decide, scope by scope, what is allowed. A full set of access control lists — congratulations, you're Microsoft again. This, once more, requires something a lot more complex than can be safely relegated to code in a cfg file. Rather, in the Security tab, these options can be explained to the user and particularly bad combinations can trigger warnings our outright blocks (here, at this level, is where it might be appropriate to allow overrides via cfg file edits). All that to make sure we don't get a slew of malicious code out there, combined with malicious suggestions for “solutions” that leave the client wide open. Again, the problem here, as others have mentioned, is that users will just be faced with an error box and go search for the first available solution. This will not be your clean three-line autoexec addition, but rather something far more malicious. ED's official answer and suggestion needs to be the first hit on every search engine, and anything that deviates from that should come with a huge warning that the player will notice. The information campaign needed to combat malicious use of this new security hole is immense. Let's just be kind and say that huge information campaigns are… not ED's forte. Edited 9 hours ago by Tippis 6 ❧ ❧ Inside you are two wolves. One cannot land; the other shoots friendlies. You are a Goon. ❧ ❧
Dangerzone Posted 4 hours ago Posted 4 hours ago (edited) On 7/25/2025 at 7:17 PM, Special K said: This is what the closed beta is. If it would not be easily accessible and servers would not show up, who should run that and who should play on it? You are correct - this is close to what CB is. This would basically be a step between closed beta and open beta, to give those that don't have closed beta access opportunity and time to test and prepare for the official release (as I presume the closed beta testers currently have?). The reason I advocate for making it harder to access is to prevent a repeat of the past, where the open beta effectively became the main release. My suggestion still allows those who genuinely want to test to do so, since access would be shared directly by DM (e.g., advising of IP address of server). It would discourage server hosts from using the beta to attract players by being "first with the module," as these servers wouldn’t appear publicly—reducing the temptation to treat the beta as a production version and avoiding a repeat of what we saw previously with the Open Beta solution. So, those who would run / those intended for would be those who specifically want to do beta testing, and fix breaking changes before it's released to public. At present, there is no opportunity for those outside of closed beta to do this. Often, non-CB server operators and mission designers find out only at release what breaking changes there are. The amount of pressure this can put on people to have to provide fixes immediately can be significant. This would hopefully help to alleviate a lot of this. Of course an additional side benefit too would be that more bugs could potentially be flagged that slip by the CB team before it reaches production servers. (This is no dig at the CB team BTW - I genuinely appreciate and value what they do and the time they donate often to test each release before it gets to the rest of us - no doubt an often thankless task that is often overlooked by the community, and comments are mostly only made when something gets through - not for all the things that they have caught). Maybe I'm out of line, or this is a bad idea for reasons I haven't seen. I understand that an Open Beta solution could bring in challenges. (Such as module release announcements - as ED in the past had basically used the OB release, not public release date of a module as it's official release - maybe in those occasional instances a OB is skipped - and only used for all the other updates?). I know I don't have all the answers here. I'm just advocating for some sort of discussion on potential solutions where we can change to assist those who are finding the current method difficult and discouraging which I'm concerned could lead to further burnout for content creators and server hosts. In the end, this comes out of a passion for wanting to see DCS be the best it can be, and reduce the amount of last minute rush some server operators and content creators need to do. Edited 4 hours ago by Dangerzone
Recommended Posts