In a message dated: Fri, 05 Oct 2001 17:06:43 EDT
"Mark Aisenberg" said:
>With eval, you can just load a perl program and run
>it. Whatever the loaded code does, it does, as if the
>loaded code was originally in your CGI program.
I think this is what I originally wanted to do, however, wasn't sure
how to get eval to do this.
>Without knowing exactly what you are tyring to do, it
>is hard to know if this is what you want. I'd guess not,
>however.
Okay, I'll try to explain it a little better. I have a perl
command-line program that I wrote some time ago. It's one of those
tools that has more options than always used, and therefore, some
thought that a web-based interface which allowed the inputting of data
in a form-based fashion and a set up default options would make life
easier.
I didn't really want to go back and attempt to turn this command line
program into a cgi program, embedding into it all the baggage that
comes with CGI and HTML, since that would unnecessarilly bloat the
command-line program. It seemed to me that a better way to do it
would be to have a separate CGI based program that takes the input
from a web page and then handed it off to the command line program
was a much better design. This allows the command line program to
not require all the CGI crap, yet allows those who prefer the simple,
web interface to have their way also.
So, now I have the basic web interface fleshed out, and for the most
part works pretty well. All I have to do is figure out how to get the
data from the CGI into the command line program, yet also have the
command line program send it's output (ideally both STDOUT and STDERR)
back to the browser.
I've currently set it up like this:
$command = "/usr/local/bin/foo";
@args = ("-vv", "-d", "$opt1", "-s", "$opt2", "-c", "$comment");
system ("$command", @args);
However, and this is what prompted my initial post, I was unsure as
to how safe this is, and it didn't provide the STDERR I was hoping
for (though, use Carp ('FatalsToBrowser'), or something like tacking
a "2>&1" on the end, etc. might help).
>In the more common case where you have a program that you
>or someone else wrote independently, and you just want to
>run it and get its output, you could use backticks.
I thought about using the backticks, but for some reason thought
there was something inherently unsafe with this. Additionally, I
thought it might be less efficient than using something like eval,
since I was (am?) under the impression that with system/backticks,
you end up spawning a new instance of the perl interpreter, but with
eval you don't. (Is this a mistaken understanding of how these things
work?)
Also, with backticking, I've always used it when I wanted to do
something with the output after the fact. In this case, I want the
output to appear in the browser as it happens since I have no need for
munging any of the output; i.e., I want the user to see the same
output regardless of the interface they choose to use, browser or
command line.
>As always, take lots of care when using backticks or system or similar
>things in your program; if a bad guy can give you input that changes
>the path to the program you want to run, he can do enormous damage.
Well, since the original command line tool requires system level
priviledges (i.e. root), anything done via either interface is
going to be potentially harmful. However, since to run the command
line tool, one will need root access to begin with on a specific
machine, if they wanted to harm the environment, chances are they
won't use this particular tool to do so. The CGI interface is *meant*
to be an internal-only, not internet accessible, and be SSL-enabled.
Additionally, the user in question will also be authenticated as
having root permissions (i.e. member of group root/wheel/sysadmin,
etc.)
I am obviously very concerned about the security of the CGI
interface, since it does allow for so many more possibilities for
compromise, which is what led me to posting initially.
I want the CGI program to essentially cobble together a list of
arguments for the command line program to deal with. However, I'm
not sure of the best way to accomplish this. Should I pass the arg
list to the external program using system(), backticks, open(), or
eval? Which is the safest, method, and which is most efficient
(I understand these may be mutually exclusive charactersistics :)
>From a pure programming perspective, I can easily accomplish my
desired end-result with what input everyone has provided so far
using either backticks, system, or open. However I'm still fuzzy on
the eval concept, having never used if before and not having a good
grasp of how to do so effectively. I'm also curious to learn a
little about secure programming, since I've really worried about it
before (as my perl stuff tends to be mostly for my own use,
not the use of others).
>I'm sure there are other approaches.
There are subleties to all of these, so it might be useful to know
>more about the specifics of what you are doing; it might affect
>security, blocking behavior, etc.
It's the various subleties involved that I'm hoping to discover.
I hope I've explained this in enough detail to evoke more discussion,
and even more questions.
>Chapter 16 of the Perl Cookbook goes into all of this at some
>length.
Great, I'll check it tonight when I get back to my oasis, er home,
where I keep my camel family :)
Thanks a lot for everyone's input, it's been quite useful and
informative!
--
Seeya,
Paul
----
God Bless America!
...we don't need to be perfect to be the best around,
and we never stop trying to be better.
Tom Clancy, The Bear and The Dragon