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.
Related
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.
I need to run this shell command in a C++ script:
"/usr/local/bin/mjpg_streamer -i "/usr/local/lib/input_uvc.so" -o "/usr/local/lib/output_http.so –w /usr/local/www" -b"
This command launches an application which broadcasts a video feed. When I execute this command via system() in C++ the application doesn't start properly.
I use:
system("/usr/local/bin/mjpg_streamer -i \"/usr/local/lib/input_uvc.so\" -o \"/usr/local/lib/output_http.so –w /usr/local/www\" -b");
When I try to access the video stream after I started it with the C++ application the webpage returns:
501: Not Implemented!
no www-folder configured
I can't expect you guys to give me an application related solution, but I'm wondering if there's a difference in the way commands from a C++ application using system() and commands directly entered in a terminal are executed.
EDIT: The application broadcasts the video stream on IP:8080. I access it by going to that IP in my browser. Usually it opens a webpage with the stream in it but when I execute the command with the C++ application I get that error.
Edit: The old idea of mis-placed quotes was wrong; I realize that -w is actually an option to output_http.so, so the whole shebang must be passed as a single parameter to the -o option, as shown here or here etc.
In that case, check file permissions etc. Does /usr/local/www exist? Is it possible that you are running the shell command from a root shell?
Hey, I have a book recommendation, too, "one of the best tech books ever published": Stevens' Advanced Programming in the Unix Environment. The guy knows -- sorry: knew -- what he was talking about.
I would avoid using the system(3) library function, or at the very least, check its returning error code. I don't understand why you are using " inside your command (I believe that in your particular case, you don't need them; but in general beware of code injection!). Read about globbing
You could use popen(3) to at least get the output of the command.
Even better, code yourself the running of the mjpg_streamer program using the fork(2) & execve(2) & waitpid(2) and other syscalls(2) (perhaps pipe(2), poll(2), dup2(2) etc...). Read Advanced Lnux Programming for more.
I am invoking c/c++ from PHP using shell_exec(Server is httpd).
Is there any way where I can directly execute c/c++ executables from apache?
So the Apache will always execute only 1 executable each time (this file acts as a router). And then this executable will take care of the rest.
Thanks
You can execute it via Apache's CGI (or FastCGI) interface.
I'm not sure I get your question correctly, but if you just want to execute a lot of system commands from your script, then it doesn't really matter who calls them - you still end up having to spawn new processes and pay the price for that. If you don't want to run the commands asynchronously, e.g. if you always need one result to proceed to the next step, then just keep using shell_exec.
Unless I'm misunderstanding and you are actually compiling C++ code from within your PHP script. That'd be something else.
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.