This mods tries to add a less trusted kind of mods than those in secure.trusted_mods. But these new kind of semi-trusted mods are still allowed to use require. With this they have practically the same priviledge level as usual trusted mods.
If you want to provide a more secure way of require, you can make this wrapped require available in the insecure env, so other trusted mods can use it.
Also, there are several things broken with the implementation (many unfixable without engine support). Obvious things: Other mods can simply overwrite settings that don't start with secure.. They can also overwrite other things (and therefore hook into), such as core.settings, core.get_current_modname (note also that this mod might not be the first to be loaded), or your unsafe_require API function. And another mod could your mod make call one of its functions, so core.get_current_modname will never be correct (this is also why core.request_insecure_environment can only be called directly from the mod's init.lua).
Yes, thats why I named it ->unsafe<- require. I mentioned in the description that it is only meant for local development purposes and should not be used on public servers. I moved that to be the first section.
All used functions (like get_current_modname) are stored as local variables - if this is not safe then core.request_insecure_environment is also not "safe".
All "secure.trusted_mods" modules must be loaded first, if an insecure mod is loaded before that, it could potentially interfere even with core.request_insecure_environment itself and intercept that, too.
So if a mod is listed in secure.trusted_mods is does not need this module to require something. If it is not listed in secure.trusted_mods it can not replace core.get_current_modname before this mod is loaded. This mod explicitly does not use core.get_current_modname() or other functions at runtime (when another mod calls unsafe_require) for exactly the reasons you mentioned. We use the values which were stored in locals at load time.
I changed the settings prefix to be secure.unsafe_require.allowed_for.modname, to prevent mods from changing this setting at runtime.
To summarize, it is in my opinion definitely better to have only one well reviewed mod which only provides a small subset (the require) compared to many modules using request_insecure_environment in an even more dangerous way.
All "secure.trusted_mods" modules must be loaded first,
There is an issue for this (https://github.com/luanti-org/luanti/issues/12182). But it was never implemented.
Please don't rely on such things unless you got them from a reliable source (i.e. official doc or source code).
All used functions (like get_current_modname) are stored as local variables - if this is not safe then core.request_insecure_environment is also not "safe".
All "secure.trusted_mods" modules must be loaded first, if an insecure mod is loaded before that, it could potentially interfere even with core.request_insecure_environment itself and intercept that, too.
core.request_insecure_environment is special, as briefly mentioned in the last sub-sentence of my comment. It checks the stack to see if it's called directly from a mod's init.lua. If you'd overwrite it, the wrapper function would appear there.
You might also want to check the source code (grep for l_request_insecure_environment).
it is in my opinion definitely better to have only one well reviewed mod which only provides a small subset (the require) compared to many modules using request_insecure_environment in an even more dangerous way.
Providing an easier to use insecure env does make sense. (One could for example also run trusted scripts in a separate lua state (https://github.com/luanti-org/luanti/issues/15071), this could maybe be provided by a trusted mod.) But my point was that it's still the same priviledge level as a normal trusted mod (i.e. if it wants to, it can do as much harm as a trusted mod). Having a separate list of trusted mods that can only access the easier to use env is nice to have if it doesn't hurt, but if one can't implement it securely (and I don't think one can (because luanti is shit here)), it does hurt.
(Side note on terminology: "Mod" is not agreed upon to be an abreviation for "module". Just call it mod. ;))
This mods tries to add a less trusted kind of mods than those in
secure.trusted_mods. But these new kind of semi-trusted mods are still allowed to userequire. With this they have practically the same priviledge level as usual trusted mods.If you want to provide a more secure way of require, you can make this wrapped
requireavailable in the insecure env, so other trusted mods can use it.Also, there are several things broken with the implementation (many unfixable without engine support). Obvious things: Other mods can simply overwrite settings that don't start with
secure.. They can also overwrite other things (and therefore hook into), such ascore.settings,core.get_current_modname(note also that this mod might not be the first to be loaded), or yourunsafe_requireAPI function. And another mod could your mod make call one of its functions, socore.get_current_modnamewill never be correct (this is also whycore.request_insecure_environmentcan only be called directly from the mod's init.lua).Yes, thats why I named it ->unsafe<- require. I mentioned in the description that it is only meant for local development purposes and should not be used on public servers. I moved that to be the first section.
All used functions (like
get_current_modname) are stored as local variables - if this is not safe then core.request_insecure_environment is also not "safe". All "secure.trusted_mods" modules must be loaded first, if an insecure mod is loaded before that, it could potentially interfere even withcore.request_insecure_environmentitself and intercept that, too.So if a mod is listed in
secure.trusted_modsis does not need this module to require something. If it is not listed insecure.trusted_modsit can not replacecore.get_current_modnamebefore this mod is loaded. This mod explicitly does not usecore.get_current_modname()or other functions at runtime (when another mod callsunsafe_require) for exactly the reasons you mentioned. We use the values which were stored in locals at load time. I changed the settings prefix to besecure.unsafe_require.allowed_for.modname, to prevent mods from changing this setting at runtime.To summarize, it is in my opinion definitely better to have only one well reviewed mod which only provides a small subset (the
require) compared to many modules usingrequest_insecure_environmentin an even more dangerous way.Thank you for your valuable feedback!
There is an issue for this (https://github.com/luanti-org/luanti/issues/12182). But it was never implemented. Please don't rely on such things unless you got them from a reliable source (i.e. official doc or source code).
core.request_insecure_environmentis special, as briefly mentioned in the last sub-sentence of my comment. It checks the stack to see if it's called directly from a mod's init.lua. If you'd overwrite it, the wrapper function would appear there. You might also want to check the source code (grep forl_request_insecure_environment).Providing an easier to use insecure env does make sense. (One could for example also run trusted scripts in a separate lua state (https://github.com/luanti-org/luanti/issues/15071), this could maybe be provided by a trusted mod.) But my point was that it's still the same priviledge level as a normal trusted mod (i.e. if it wants to, it can do as much harm as a trusted mod). Having a separate list of trusted mods that can only access the easier to use env is nice to have if it doesn't hurt, but if one can't implement it securely (and I don't think one can (because luanti is shit here)), it does hurt.
(Side note on terminology: "Mod" is not agreed upon to be an abreviation for "module". Just call it mod. ;))