www-data user is the user, from whose behalf Apache runs your WordPress code (and any other code, generating Web pages for your users, e.g. Django code - python web-site engine).
www-data user is created to have minimal permissions possible, because it can possibly execute malicious code and take as much control over your system, as it is allowed to take. Suppose, that WordPress engine contains a vulnerability. Say, it allows the user to convert an image file from
.gif format by running
convert from Imagemagick. The vulnerability is that it doesn't check that the filename contains the filename and only filename.
If a malevolent cracker supplies "image.png; ldd image.png", and WordPress executes
convert image.png; ldd image.png in the shell without filtering out
"; ldd image.png" part (this part was added to filename by the cracker in order to be exectued in the shell), your apache will run
ldd image.png in addition to converting image. If
image.png is in fact an executable file, named image.png, which the cracker supplied to you (if you allow other people to publish on your site, using WordPress engine),
ldd image.png can result in arbitrary code execution, using 'ldd' vulnerability as described here: http://www.catonmat.net/blog/ldd-arbitrary-code-execution/.
Obviously, if that code is run as root user, it can infect all programs in your system and take total control of it. Then you're screwed (your virtual hosting can start sending spam, trying to infect everyone with viruses, eat up all your hosting budget etc.).
Thus, WordPress should be run with minimal privileges possible, in order to minimize damage from a potential vulnerability. Thus, any file, that
www-data can write to, should be treated as possibly compromised.
Why don't you run WordPress as your
foo user? Suppose, you've got a per-user installation of programs (e.g. in
/home/foo/bin), and run WordPress as
foo user. Then vulnerability in WordPress can infect those programs. If you later run one of those programs with
sudo, you're screwed - it will take total control over the system. If you store any password or private key and
foo user can read it, then cracker, who hacked your WordPress will be able to read it, too.
As for the overall mechanism of Apache functioning, here is a summary:
1) On your VPS computer there's a single Apache2 process, that runs as a root. It has to run as the root, cause it needs root privileges to ask Linux kernel to create a socket on TCP port 80.
Socket (see Berkley Sockets) is an Operating Systems Programming abstraction, used by modern Operating Systems (OS) kernels to represent network connections to applications. WordPress developers can think of a socket as of a file. When 2 programs, client and server, on 2 different computers speak to each other over the network, using TCP/IP protocol, OS kernels handle the TCP/IP details by themselves and the programs just think, that they have a file-like object - socket. When Client program (e.g. Mozilla) writes something to its socket, kernel of the client computer's OS delivers that data to the kernel of server computer's OS, using TCP/IP protocol. Then Server program (Apache2 on behalf of WordPress) can read those data from its socket.
How does client find the server and how server distinguishes between clients? Both server and client are identified by a pair (IP address, TCP port number). There are well-known ports for well-known protocols, such as 80 for http, 443 for https, 22 for ssh etc. Well-known ports are used by server computers to expect connections on them. IMPORTANTLY, only root user can create sockets on well-known ports. That's why the first instance of Apache2 is run as root.
When a server (Apache2) program wants to start listening to a port, it creates a so-called
passive socket on port 80 with several
system calls (socket(), bind(), listen() and accept()). System call is a request from a program to its OS kernel. To read about system calls, use e.g.
man 2 socket (here
2 means the section 2 of man pages - system calls, see
man man for section numbers).
Passive socket can't really transfer data. The only thing it does is establish the connection with client - Mozilla's tab.
2) Client (Mozilla tab) wants to establish a TCP/IP connection to your server. It creates a socket on NON-WELL KNOWN port 14369, which doesn't need root privileges. Then it exchanges with 3 messages with Apache through the passive socket on your server computer's 80th port.This process (establishing the TCP/IP connection with 3 messages) is called 3-way handshake, see:
3) When TCP/IP connection is successfully established, Apache2 (run as root) invokes
accept() system call and Linux kernel creates an
active socket on server's 80th port, corresponding to connection with Mozilla's tab. Through this active socket will your WordPress application talk to the client.
4) Apache2 (run as root) forks another instance of Apache2 to run the WordPress code with lower privileges. That instance will run your WordPress code as a
5) Mozilla and Apache2, running WordPress code as
www-data user start exchanging http data over the established connection, writing and reading to their respective sockets via
send()/recv() system calls.
Basically, WordPress is just a program, whose output is an html-page, so Apache2, running as a
www-data just runs that program and writes its output (html-page) to the active socket and Mozilla on the client side receives that page and shows it.