I strongly disagree that running something with higher privs from a web server is always a bad idea.
The security problems from a web application come from trusting the user-supplied data, not from the exact process that's using that data.
In other words, if you don't validate and sanitise your data, it's no safer to pass it to a root-owned process via named-pipe than it is to write a wrapper script to process that data and allow the www-data user to run it via sudo.
Actually, most of the processing/validation/sanitising of data should be done before the data is passed to the sudo script, which should a) do a final check on the data, and b) perform only the operations that need higher privs.
In fact, I'd argue that it's possibly safer to do the latter because it's a simpler solution that's easier to understand....the more complicated you make something, the more likely you are to make a mistake.
Whichever method you use (named-pipe, sudo wrapper, or whatever) the crucial thing is that you examine the user supplied data and make sure it fits very narrowly defined criteria before doing anything with it.
There are numerous articles and howtos on CGI security on the web, including several here on the stackexchange sites, but some of the common themes are:
- regard the data as 'tainted' and untrustworthy until you've checked it and/or modified it to make it safe.
- check the data - e.g. test if it matches a regexp of allowed or prohibited characters. safest option is to abort if there's anything odd, otherwise transform it with a regexp or something to remove potentially unsafe elements.
- always quote the data if you pass the data to an external shell script. e.g. the shell script should use double-quotes around the variables.
- similarly, when inserting data into database you should use a database library that supports placeholder values rather than relying on escaping or quoting. Here is a humorous illustration of why.
I could go on, but there's too much to summarise in an answer here - CGI Security is a broad topic. Try a google search for CGI Security or Validating CGI Input
With your 'I don't care because it's only me using it' attitude to security,
I kind of feel like I'm giving you a loaded shotgun to blow off your feet with, but shooting yourself in the foot is a valuable learning experience. Here's a simple script to create a user account. It requires root privs.
The script relies on adduser, which is available on debian and debian-derived systems and maybe others. modify to use useradd instead if it's not on your system.
# make the script abort on any error
[ -z "$U" ] && echo "Error: No username provided" >&2 && exit 1
[ -z "$P" ] && echo "Error: No password provided" >&2 && exit 1
# simple check - only allow lower-case letters and digits in usernames.
[ "$U" !~ '^[a-z0-9]*$' ] && echo "Error: Invalid Username" >&2 && exit 1
# create user if they don't already exist
if ! getent passwd "$U" > /dev/null ; then
# create the user using adduser, must provide the gecos field
# and disable the password so adduser doesn't ask for them.
adduser --gecos "$U" --disabled-password "$U"
# now change the password
echo "$U:$P" | chpasswd
echo "Error: Username already exists" >&2
Save the script somewhere, and make it executable with chmod.
To allow www-data to run it as root without a password, edit /etc/sudoers with
visudo and add the following:
Cmnd_Alias APACHEADDUSER = /path/to/makeaccount.sh
www-data ALL = NOPASSWD: APACHEADDUSER