I need to make a kind of gnuplot web interface, that receives a list of commands or a file, saves it to disc and tells gnuplot to render it into png (“set terminal png; set output…”).
What nasty or stupid things can user do with it (e.g. overloading cpu or RAM, accesing filesystem…)?
How can I avoid them? What potentially malicious lines should I remove before passing code to the gnuplot?
I’m running gnuplot via subprocess.Popen from django.
DISCLAIMER — THIS LIST IS BOUND TO BE INCOMPLETE
There are a few things that you’ll want to disable (in the least).
in gnuplot, take a look at
help shell— Those allow the user to spawn an interactive shell (anything betweenshellandlogoutwill need to be discarded). Also, you’ll want to remove any lines starting with!orsystem(and any line continuations) as those invoke shell commands. Next on my list of potentially hazardous things to do is using backtic substitution.will clear out your home directory. Of course, I make no claims that if you do all these things, your script will be completely safe. If you’re only allowing the user to upload one file to run, you might as well disable
loadandcallas well since then you don’t have to worry about the user somehow uploading another malicious script and loading it from the first.Another thought — gnuplot allows programs to be called using pipes — e.g.
You’ll need to pretty much disable any string which starts with whitespace followed by
<or a|— possibly with escape sequences in there as well since gnuplot might just silently throw those away if they’re not escaping anything.and another …
You could also get the script stuck in an infinite loop quite easily using
reread— That script is just one line long:This is one you’ll probably want to disable even if you construct a chroot jail to run your scripts under (something that I know nothing about, I only learned the term while googling how to run a script safely under unix…) — Although I suppose using the above methods, a user could still peg your one core of your CPU by constructing an infinite loop in a different programming language and executing that from gnuplot — Same thing goes for memory I guess…
The more I think about it, in order to do this safely, you pretty much are going to have to re-write the gnuplot parser from scratch and check everything, (or sandbox and monitor — setting careful limits on consumed resources).
(sorry, I’m sure this isn’t what you want to hear).
It seems (to me) like your best bet is to create your own mini-language which accepts only a small (but useful) subset of gnuplot commands and constructs the gnuplot script from that set of commands …
PROGRESS EDIT
After playing around a bit, you can disable piping in gnuplot —
Now, you need to edit
config.hthat was generated by configure…comment out the lines:
and
and
(e.g.
/*#define HAVE_PCLOSE 1*/if you’re not familiar with C comments).then
make; [sudo] make install— with the suffix the way I’ve set it up, your “safer” version of gnuplot can be invoked asgnuplotsafer.This disables the insecurities that arise from pipes (problems with strings that have
|,<, and even backtics are now safe). shell, system and ! are still not safe, youll have to disable those by parsing the script still — but that is ALOT easier than trying to make sure the user doesn’t set up malicious pipes.
I would also suggest that you check to make sure you can’t do anything with the pipes/backtics, etc before you put the system online, and I would still try to sandbox the entire thing as much as possible.