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?
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.
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.
Related
I want my program to download some audio file from a link I give it and save it.
I know this can be easily done in the command line using curl (for instance: curl -A "Mozilla" "www.example.com" > hello.mp3
I saw examples where system() was used to run curl (i.e it looked something like system(curl -A "Mozilla" "www.example.com" > hello.mp3) . Even though this is an easy solution it seems bad to me.
Would it be better practice to write an equivalent code using the matching library (libcurl in this case)?
What do you guys think?
P.S - This is a general question in a sense. What I mean by that is that there are many command line programs which can be run by system() to get a fast and easy result. The question is if it's okay to use this method to achieve it.
Yes, it would be better to use libcurl directly. That's what it exists for.
That way, you avoid:
the cost of a system call
the cost of spawning a new process
potential security-related bugs in your system call
Invoking curl from the shell will basically just spawn a new shell and new process for no reason, then go ahead and use libcurl inside that process anyway. Cut out the middle man.
I am writing some library code which will rerun the current process as an administrator/root. The problem is (for linux at least) that if the calling code is a command line application the best way would be to call sudo whereas if it is a gui application, gksudo is appropriate. For completeness sake though, solutions (or pointers to solutions) for other os's are also welcome.
Also, this is useful so that for GUI apps, I can turn off printf statements.
I'd run gksu(do) if the environment variable DISPLAY is set. It doesn't really matter if the application has a GUI or not, if there's an X-server running, and we can use it, why shouldn't we?
Doesn't allow you to determine if you should disable stdout output. However, stderr output is generally captured in .xsession-errors, even if no terminal is connected, so you might not want to disable that output afterall.
I am designing an C++ app that, among other things, executes a few scripts every now and then. The app should be efficient and preferably platform independent.
The issue is, however: is there a reason one shouldn't use system() call for launching scripts and use, for example, POSIX facilities instead? The discussion on the matter that I've seen so far usually boils down to:
system() is less flexible. (Fine with me)
It offers no control of the command being executed. (Fine with me, I just need a return value from the script)
It is not quite platform independent. (Now, this would be a concern. I would really love to see an example where it behaves differently on different platforms)
It is a security concern. (Again, this would be an issue. Can someone provide an example of a potential security problem with system()? )
Any other issues?
3) It is not quite platform independent (Now, this would be a concern. I would really love to see an example where it behaves differently on different platforms)
Well, for instance system("ls") would probably fail in Windows, since there is no ls command.
4) It is a security concern. (Again, this would be an issue. Can someone provide an example of a potential security problem with system() ? )
If the argument passed to system comes from user input, and not properly validated, it can be used to execute unwanted things with the privilege levels of the original executer. If its static content, its quite easy to find that within an executable image and modify it to do nasty things as well.
(3) If you just want a counterexample, for example grep behaves differently on Solaris vs Linux vs whatever.
(4) Your program's privileges are inherited by its spawned programs. If your application ever runs as a privileged user, all someone has to do is put their own program with the name of the thing you shell out too, and then can execute arbitrary code (this implies you should never run a program that uses system as root or setuid root).
(5) It will probably be saner to maintain in the long run to use the posix facilities because you won't have to rely on a specific set of external scripts or binaries already existing wherever your program runs.
I maintain a system that consists of several separate executables. In this case I have control over the permissions, names, calling conventions, security over all supported platforms. In this case, system() works just fine. The applications communicate through a RDBMS.
Again, as others have noted "The Devil's in the details".
Regarding security concerns, a classical example about (4) is the following scenario: imagine the user is prompted to give some directory name to be backed up into a std::string dirname; then you'll compute some backup directory name into a std::string backup and do
system((std::string{"cp -a "} + dirname + " " + backup).c_str())
Now think what happens if a malicious user enter foo bar; rm -rf $HOME; ls as the dirname and backup is /vol/backup_2015_fev/. The system command would execute
cp -a foo bar; rm -rf $HOME; ls /vol/backup_2015_fev/
which is not what you expected (all the user's $HOME would be deleted!). This is an example of code injection, and when using system you should ensure that it never happens (e.g. by sanitizing and/or escaping every user input related string)
Also, the PATH might not be what you believe it is (e.g. starting with /tmp/ and a malicious user having done ln -s /bin/rm /tmp/cp before your system runs).
I used the system() call in my CGI C++ app under windows and Linux too.
One problem I had was when using system() was not having the proper access rights to execute my skript with the web user.
I did not have that problem any more when using the CreateProcess() method.
Whatever command you want to execute just store that in a file c.txt. Pass that file to the execl() like as done below.
fd = open("c.txt", O_CREAT | O_RDWR, 00777);
write(fd,arr,sizeof(arr));
if(fork() == 0)
{
execl("/bin/sh", "sh", "-c","sh c.txt", (char *) 0);
}
Our app is ran from SU or normal user. We have a library we have connected to our project. In that library there is a function we want to call. We have a folder called notRestricted in the directory where we run application from. We have created a new thread. We want to limit access of the thread to file system. What we want to do is simple - call that function but limit its access to write only to that folder (we prefer to let it read from anywhere app can read from).
Update:
So I see that there is no way to disable only one thread from all FS but one folder...
I read your propositions dear SO users and posted some kind of analog to this question here so in there thay gave us a link to sandbox with not a bad api, but I do not really know if it would work on anething but GentOS (but any way such script looks quite intresting in case of using Boost.Process command line to run it and than run desired ex-thread (which migrated to seprate application=)).
There isn't really any way you can prevent a single thread, because its in the same process space as you are, except for hacking methods like function hooking to detect any kind of file system access.
Perhaps you might like to rethink how you're implementing your application - having native untrusted code run as su isn't exactly a good idea. Perhaps use another process and communicate via. RPC, or use a interpreted language that you can check against at run time.
In my opinion, the best strategy would be:
Don't run this code in a different thread, but run it in a different process.
When you create this process (after the fork but before any call to execve), use chroot to change the root of the filesystem.
This will give you some good isolation... However doing so will make your code require root... Don't run the child process as root since root can trivially work around this.
Inject a replacement for open(2) that checks the arguments and returns -EACCES as appropriate.
This doesn't sound like the right thing to do. If you think about it, what you are trying to prevent is a problem well known to the computer games industry. The most common approach to deal with this problem is simply encoding or encrypting the data you don't want others to have access to, in such a way that only you know how to read/understand it.
I know that in a DOS/Windows application, you can issue system commands from code using lines like:
system("pause");
or
system("myProgram.exe");
...from stdlib.h. Is there a similar Linux command, and if so which header file would I find it in?
Also, is this considered bad programming practice? I am considering trying to get a list of loaded kernal modules using the lsmod command. Is that a good idea or bad idea? I found some websites that seemed to view system calls (at least system("pause");) in a negative light.
system is a bad idea for several reasons:
Your program is suspended until the command finishes.
It runs the command through a shell, which means you have to worry about making sure the string you pass is safe for the shell to evaluate.
If you try to run a backgrounded command with &, it ends up being a grandchild process and gets orphaned and taken in by the init process (pid 1), and you have no way of checking its status after that.
There's no way to read the command's output back into your program.
For the first and final issues, popen is one solution, but it doesn't address the other issues. You should really use fork and exec (or posix_spawn) yourself for running any external command/program.
Not surprisingly, the command is still
system("whatever");
and the header is still stdlib.h. That header file's name means "standard library", which means it's on every standard platform that supports C.
And yes, calling system() is often a bad idea. There are usually more programmatic ways of doing things.
If you want to see how lsmod works, you can always look-up its source code and see what the major system calls are that it makes. Then use those calls yourself.
A quick Google search turns up this link, which indicates that lsmod is reading the contents of /proc/modules.
Well, lsmod does it by parsing the /proc/modules file. That would be my preferred method.
I think what you are looking for are fork and exec.