Generally speaking, opening a powerful (root) program to the internet via CGI is dangerous.
For info on CGI security, see: http://www.panix.com/~comdog/CGI_MetaFAQ.html http://www.w3.org/Security/Faq/wwwsf4.html and other sources you can find with Google. If you're not an experienced CGI programmer, you might reconsider what you are doing and instead use remote control software to continue to run your command line program, but remotely. Major areas of security breaches include: * web server breaches (IIS or Apache, e.g.) * tainted user input * people pretending to be authorized users * info leakage from valid use to the outside world, where it is picked up and used by bad guys I've been writing CGI programs for 3 or 4 years now, and typically the amount of code required for security and user interface exceeds that of the core program function. I've written custom modules for my own use to handle things like session management (using whatever combination of partial ip address, cookie data, and session ids I stick in URLs and propagate from page to page), so I know that the person using a form is the person who just logged in. You have to plan to spend a few weeks learning and implementing security code before you should feel reasonably safe. Again, remote control software? AT&T has a free one at http://www.uk.research.att.com/vnc/start.html If you're still interested, maybe we could discuss it at a technical meeting of some sort (I've been planning to start attending for a couple of years now...) ----- Original Message ----- From: "Paul Lussier" <[EMAIL PROTECTED]> To: "Mark Aisenberg" <[EMAIL PROTECTED]> Cc: <[EMAIL PROTECTED]> Sent: Tuesday, October 09, 2001 12:44 PM Subject: Re: [Boston.pm] Safe execution of 1 perl prog from another? > > 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 > > >
