Jump to content

Recommended Posts

Posted
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)

 

Posted (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 by Special K
Posted (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 by eekz
  • Like 1
Posted (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 by Karlos
  • Like 2
Posted

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

  • Like 2
Posted
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 ill-suited: 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.

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.

Alternative

The suboptimal design choice for the security option unnecessarily restricts privileged states, can be easily bypassed by those states, and is ill-suited for standard use cases, e.g., Olympus + access to "mission" state from a_do_script(). It is not worth the collateral damage in terms of API incompatibility, which breaks community content.

The new security option should be removed and the behavior of the scripting system should be restored to DCS 2.9.17. 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.

  • Thanks 1
Posted
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?

  • Like 3
Posted
18 hours ago, 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.

18 hours ago, 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.

18 hours ago, 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:

  1. Hotfix-patch rollback.
  2. Do any of the things cfrag has suggested. Or see two posts above.

 

  • Like 1

❧ ❧ Inside you are two wolves. One cannot land; the other shoots friendlies. You are a Goon. ❧ ❧

  • Recently Browsing   1 member

×
×
  • Create New...