There are no such features. There is little difference in practice between "oh this program does bad things at compile-time" and "oh this program does bad things at runtime" and usually you compile a program in order to run it afterwards...
Having said that, we could add a --confirm switch to Nim and then the compiler asks you for confirmation before every staticExec run. Using regexes for this will never work reliably and simply create a false sense of security.
@Araq this functions can be used to embed malware code into your program/library and you even not notice it. Some packages from nimble repository can be hacked and some hidden staticRead/staticExec can be inserted.
Also it is possible that while building malicious application user will embed content of his own /etc/shadow or any other private information into binary.
There is little difference...
+1 to this. Also add nimblefiles to that, and then if you're using other build systems, like makefiles, or gradle, this witch hunting quickly becomes impractical. And then if we add --confirm flag, it is all-or-nothing, so once you need one staticExec, you're under the "risk" again. To conclude, I see absolutely no point in such measures, because one way or another you must trust your dependencies, be it staticExec, runtimeExec, or runtimeDoTheLogicTheDependencyIsSupposedToDoInTheFirstPlace.
Also it is possible that while building malicious application user will embed content of his own /etc/shadow or any other private information into binary.
So sandbox your build environment, it's the only thing that has a chance of working. Everything else is like cleaning your teeth with a broom, it hurts and yet doesn't accomplish anything.
@Lachu: the official Nim packages in Debian are using reproducible builds successfully.
@cheatfate: sounds like you are describing staticRead and staticExec as a way to obfuscate malicious code. There are many other ways to obfuscate Nim code e.g. with complex macros. I wonder if sandboxing a build would be effective when the run is not sandboxed.
OTOH sandboxing both build and run is certainly a good thing.
Yet, I see value in sandboxing Nimble builds to improve reproducibility across different hosts / OSes to help debugging.
I just wrote this way-too-long proposal for how staticExec/staticRead could be made more auditable. You can read it here if you want.
But then I wondered if the problem could be generalized. How much complexity would it add to allow compiler users to forbid/allow specific proc/func calls (at compile time or run-time). For instance, imagine this:
nim c --forbid:*:staticExec --allow:myfile.nim:staticExec("/bin/ls") myfile.nim
If a forbidden invocation is found during compilation, it could produce an error message like:
ERROR: Forbidden call in myfile.nim:4 staticExec("/bin/ls"). To allow, use:
--allow:myfile.nim:staticExec("/bin/ls")
or add switch("allow", """myfile.nim:staticExec("/bin/ls")""") to config.nims
Or maybe your company decides that no one should use writeFile for whatever reason:
nim --forbid:*:writeFile thecode.nim
Maybe this could exist as a macro I could make myself... maybe.
There is already logic in the compiler to prevent writeFile and staticExec for "nim check" and "nimsuggest" and it should be easy to extend this feature
as argued in https://github.com/nim-lang/Nim/pull/16943#issuecomment-773980301, there should be a flag instead to control this, because other commands may want to restrict VM, eg:
etc
I suggested instead --experimental:vmsandbox in https://github.com/nim-lang/Nim/pull/16943#issuecomment-773980301 which would create an opt-in sandbox for VM, usable by all commands (which would then restrict staticRead, writeFile as vmops, staticExec, gorge etc) . But customizing beyond all or nothing it is tricky, and maybe a --confirm flag is the simplest; it would need RFC anyways.
But the key arguments remain:
What changed?
Tools like nimsuggest, "generated asm explorer", "nim check" shouldn't need to be sandboxed, hence disabling this feature became more important to me.