Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Sudo in system() (cenains.blog)
17 points by ptsneves on Sept 21, 2021 | hide | past | favorite | 11 comments


Shell escapes may be one of the most common escaping issues I see these days. Most programmers have gotten into their heads that they need to escape SQL and HTML but for some reason the most commonly used commands to start new executables use the shell and people bang strings together to build the argument strings. Languages/libraries should make it incredibly obvious which strings are passed to the shell and ideally would apply protections such as automatic escaping that is frequently done for HTML.

But the thing that I don't get the most is that passing a list of arguments is easier than using the shell in a lot of cases. I frequently see people build a list of arguments then join it by spaces! Save yourself a step and just pass the list to `exec` directly.


I think the post is really confused about what that advice is trying to talk about. It's not talking about programs which call system("sudo ..."), but rather programs which have privileges which want to run other programs. The behavior of system() is controlled by many environment variables, which means that it's tricky for such a program to be able to safely use system() without allowing for a security hole of using the privileged program to run another arbitrary program as root.


> which means that it's tricky for such a program to be able to safely use system() without allowing for a security hole of using the privileged program to run another arbitrary program as root.

Not entirely and this is what the post mentions. That compromise of the program calling systemd("sudo <...>") does not necessarily lead to full blown privilege escalation, because the sudoers file can be crafted into letting sudo run pre-specied privileged programs including pre-specified arguments.

Also the compromised system caller will not be able to use poisoned environmental variables to influence the privileged program ran by sudo because sudo wipes the environmental variables by default, before running the privileged program.


But where does system() come in to play then? If you're not dealing with privileged/setuid programs, then a program which calls system() isn't doing anything that you couldn't do yourself. A well crafted sudoers file can help control what gets run with sudo, but that happens regardless of how sudo is invoked.


> Delete your /etc/environment

Do what now?


Honestly, this entire post reads like a fever dream.


I don't even know why. On my distro, there's nothing in it by default anyway.


Maybe it could be more explicit but the reasoning comes from the sudoers manual page[1]:

> By default, the env_reset flag is enabled. This causes commands to be executed with a new, minimal environment. On AIX (and Linux systems without PAM), the environment is initialized with the contents of the /etc/environment file.

So if you want to make sure there are no sudo commands relying on PATH or any environmental variable you just delete the /etc/environment or set it empty. Like it says in the post, Ubuntu has the $PATH variable in it, and in other distributions it is just empty. The deletion suggestion is for systems where there is a big degree of control over the system, like embedded distributions built with yocto or custom container images.

[1] https://linux.die.net/man/5/sudoers


sudo relying on the PATH provided by /etc/environment is safe... What isn't is system() relying on the current PATH, provided by the (unprivileged) caller.

The author is so very confused. Not a single argument actually in favor of system(), as opposed to execve() which is the alternative mentioned in manuals next to "don't use system".


execve does not do the same as system at all, as per manual

> execve() executes the program referred to by pathname. This causes the program that is currently being run by the calling process to be replaced with a new program

The argument in favor of system is that it is a standard C library function. It is clearly in the article: > Better, while we are being pragmatic why not use good old system C stdlib function


I meant fork+execve, obviously if you drop execve where system is, it doesn't work the same.

You make a good point about it not being standard. Is there no standard way of creating a process from an argument vector, without dealing with the shell?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: