0

I have read a lot of answers saying that the system() command is bad. First off, why is it so bad? Second off, is there an alternative that doesn't produce such a security hole? I mostly want to know if there is a way to clear screen in C++. In python I have a clear function that checks the os name and runs either system('cls') or system('clear'). Is this a security hole as well? If so, is there a python alternative?

drescherjm
  • 10,365
  • 5
  • 44
  • 64
RedSox2
  • 7
  • 8
  • Does this answer your question? [Issuing system commands in Linux from C, C++](https://stackoverflow.com/questions/4622693/issuing-system-commands-in-linux-from-c-c) – Chelmy88 Oct 15 '20 at 18:00
  • Handy reading: [Why should the system() function be avoided in C and C++?](https://stackoverflow.com/questions/19913446/why-should-the-system-function-be-avoided-in-c-and-c) – user4581301 Oct 15 '20 at 18:01
  • 1
    If you're only looking to clear the terminal and you're on a UNIX system, you can use ANSI escape codes and avoid calling another program entirely. See [Clearing terminal in Linux with C++ code](https://stackoverflow.com/q/4062045/2602718) – scohe001 Oct 15 '20 at 18:02
  • No, I am on a Windows 10 home os. – RedSox2 Oct 15 '20 at 18:05
  • You probably should not use system("cls") to clear the console. – drescherjm Oct 15 '20 at 18:06
  • 2
    Search [softwarerecs.se] for a cursor positioning library. Many of those have functions to clear the console. – Thomas Matthews Oct 15 '20 at 18:06
  • Does the `\033[2J` not work on Windows? – RedSox2 Oct 15 '20 at 18:07
  • Why this isn't built into C++: C++ is a very big tent with support for a staggering array of hardware and operating systems, and not all of them have a clearable console. Or much of a console, for that matter. Mandating that implementers add in support for clearing a console they don't even have is seen as a bit of a move. – user4581301 Oct 15 '20 at 18:25
  • "*I mostly want to know if there is a way to clear screen in C++*" - for Windows, see [Clearing the Screen](https://learn.microsoft.com/en-us/windows/console/clearing-the-screen) on MSDN for an alternative that doesn't involve using `system("clr")`. – Remy Lebeau Oct 15 '20 at 19:24
  • I believe you mean `system("cls")` – RedSox2 Oct 15 '20 at 19:32

2 Answers2

2

system functions (across many language, including Python and C++) are not inherently "bad" but they present difficulties for correct use.

Security

You need to be absolutely sure that whatever you're executing via system is secure.

If you write system("echo hello " + name) then you need to be absolutely sure that name cannot be controlled by a malicious user. name = "; rm -rf /" would result in echo hello ; rm -rf /, so if that's coming from a user, via something like a web form or a database, then you need to exercise a lot of caution, and I would recommend a more sophisticated solution than system.

A call like system("clear") is secure for your purposes.

Usability

System calls give you several outputs (I'll give an example for calls to a bash shell):

  • status code (whether the shell indicated an error condition)
  • contents of STDOUT
  • contents of STDERR

system returns the status code. For commands like ls, you are interested in receiving STDOUT, and you may also check the status code. This is unwieldy with system.

The Python subprocess module is generally accepted by the community as an easier way to manage these concerns.

How to manage the console

If you're trying to manage the console display, you may be interested in a library like ncurses which has broad OS support.

Adding ncurses as a dependency could be heavy-handed, if clearing the screen is the only thing you need to do. If that's the case, then I see nothing wrong with using system() like you're doing.

ajm
  • 144
  • 7
  • When I use the `system("cls");` command, the command prompt goes crazy, and just prints line after line and doesn't stop. Is there a reason for this? – RedSox2 Oct 15 '20 at 19:21
  • Actually, only when I use the Path variable for it. If I am in the workspace it works just fine. Is there a reason for this? – RedSox2 Oct 15 '20 at 19:23
  • @RedSox2, what is "when I use the Path variable for ti" supposed to mean in terms of running `system("cls")`? Which workspace works fine? – Eryk Sun Oct 16 '20 at 08:08
  • _@ajm_ _"If you write `system("echo hello " + name)"`_ Please note, that this won't be possible directly, supposed that `name` is of type `char*`. The command needs to be constructed either using a `std::string`, or `strcat()`. – πάντα ῥεῖ Oct 16 '20 at 10:10
  • In windows there is your `Path` variable which allows you to run .exe files quicker (e.g. you have to put the path to the min-GW bin in your path variable for it to work). So instead of navigation to the folder everytime I run command prompt, I can just type in `%foo%` if the file I want to run is foo.exe. – RedSox2 Oct 16 '20 at 16:20
1

First off, why is it so bad?

Because you introduce dependencies to the OS in your code, and make it unportable.

Second off, is there an alternative that doesn't produce such a security hole?

No, the existing alternatives (POSIX compatible) fork() and execxx() or pipe() have the same problems of introducing OS dependencies and security holes.

Is this a security hole as well?

The main secuity hole is introduced with commands constructed from parameters like

void exec_ls(const std::string param) {
    std::string cmd;
    cmd = "ls -l " + param;
    system(cmd.c_str());

If someone manages to inject some additional command via param, e.g.

 std::string param = "dir ; rm -rf /*";
                       // ^^^^^^^^^^^
 exec_ls(param);

they can call all kinds of malicious commands. Another security hole comes from the point, that someone might replace cls or clear commands on your system with some malicious code.
The only way to get over this, is to secure your system in a way, that such isn't possible.

If so, is there a python alternative?

Using a different programming language as an intermediate caller doesn't fix the problem I mentioned above.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • The security hole with `system` is that it runs the command via the shell, which is a *scripting language*. If you're just letting the user run an arbitrary command, that's fine. Whatever the result; it's their fault. But if you're allowing the user to supply arguments for a template command, it is completely your fault if you choose to run the command via `system`. That would be gross negligence. – Eryk Sun Oct 16 '20 at 08:20
  • @ErykSun Added a more realistic example than in the other answer, for that matter. – πάντα ῥεῖ Oct 16 '20 at 10:19