modified/modern thttpd (v2.27 Oct 2015) tiny/turbo/throttling HTTP server by Jef Poskanzer
For modern compilers, there is also a bug and security fixed v2.25b (Dec 2003) thttpd on github, maintained by Anthony G. Basile blueness@gentoo.org https://github.com/blueness/sthttpd
As of v2.29 (23 May 2018) Jef's version of thttpd will also now compile with modern compilers http://www.acme.com/software/thttpd/ (he has some other interesting things there too)
I have added as many missing or applicable patches from Anthony's for of thttpd. However the base of this version already has ol_strcopy() to replace all the memmove() calls, which means some patches are not required any more. I also did not apply the "Clean up free() calls" patch, as I develop for MiNT on Atari ST, sometimes gcc is v2.98, "free( void() ... )" needed there, so I also keep configure.in and not changeto configure.ac (as Anthony has done with sthttpd). At worst they will be compiler warnings, not compiler errors.
I have not applied the monotonic timer fix. Until I can test the fix with old build systems, I cant afford to change a core component.:
src/timers.c: Fix monotonic clock support on systems without librt
However it appears monotonic clock was implimented in 2012, so we will see. "old build systems" also dont support configure.ac and Makefile.ac , but "new build systems do support configure.in & Makefile.in still.
mthttpd comes with a php.cgi script and an example thttpd configuration file that will quickly and simply allow ANY version of PHP to be run in its CGI form (eg. php5-cgi) using CGI path overloading. It will also work with any thttpd server version, including "premium thttpd" (not tested). Some PHP applications may break, usually due to assumptions made about environment variables and their contents being made available to PHP. See PHP Manual quote below for an example of CGI path overloading.
I have a file manager application originally developed with PHP v4, using (standard) PHP SAPI modules for Apache, it runs 100% fine using CGI path overloading (which can also be done with Apache too). http://navphp.sf.net/
A benificial side affect of this is that multiple scripts can run multiple PHP versions (v3,v4,v5,v6,v7), as well as any other command line interpreter that outputs to STDOUT (eg. BAS - ANSI BASIC interpreter, CINT - C/C++ 2011 Interpreter).
To assist in Apache migration and general PHP development, mthttpd now directly outputs the PHP specific environment variable SCRIPT_FILENAME, along with the Apache variables DOCUMENT_ROOT and REDIRECT_STATUS. It also sets the internal default web server user group to www-data (was www).
Those environment variables are constructed in the php.cgi script, however when output internally, they will allow mthttpd to run executable .php scripts using the binfmt_misc method directly.
As I understand it, the main reason SCRIPT_FILENAME is not included in thttpd was because it was not part of the offical CGI standards. However with SCRIPT_NAME how does one know where the web server root is if DOCUMENT_ROOT is not supplied. After testing with php.cgi the following assertions can be made:
- SCRIPT_FILENAME is not the same as SCRIPT_NAME
- PHP_SELF does NOT refer to SCRIPT_NAME
- PATH_TRANSLATED is NOT present without CGI path overloading
- PATH_TRANSLATED is the only variable to pass the FULL path through the webserver to the intended script
- DOCUMENT_ROOT is required otherwise the webserver root must be hardcoded somewhere else
- DOCUMENT_ROOT + SCRIPT_NAME = SCRIPT_FILENAME
The above assertions are (mostly) not true in PHP SAPI modules. In a more traditional sense binary programs were never ment to set environment variables. The Unix philosophy would dictate a specific shell environment would set the variables, and a binary would just update them when that environment was passed along. This was fine for production environments, however, especially in "modern" times, the same can not be said for development environments.
It is possible for a single instance of thttpd to spawn seperate instances for a given hostname on a per user basis, however this requires a CGI with access to the system, and webserver users being OS users. OS users would also allow for other services to be easily secured (like ftp, git, etc), because the filesystem rights would already be correct.
This allows a login.cgi to spawn a new thttpd as a different user, however it does require a different port number (not 80) on multi-homed IP hostnames. Xinix OS is an example of this (2017). This allows thttp to support "sandboxed" script execution, which is great for developers, especially in a production environment.
thttp relies almost exclusively on filesystem rights. However by default it will list files and folders beginning with "." (dot), which on most filesystems, are normally hidden without the need for special attributes. This will be the next addition I make, a config option to see dot files, set to not view them by default. That will hugely improve default security in a production environment, where it is sadly a requirement nowadays.
With mthttpd not showing dot files, in chroot mode, you will be able to securely hide binaries while still being able to provide secure public /cgi-bin/ paths. This also allows thttpd folder password protection system to become more secure.
CGI path overloading is not a new thing, nor is it insecure in most instances, except posibbly where the target CGI is the actual scripting engine binary. Even then it is not insecure by default. There are still web applications and web games being developed today (2017) that use CGI path overloading as a default (and secure) script application security solution.
If in doubt, especially on a production server, then use chroot option (a list of minimal files is present in CHROOT.md).
A quote for the PHP Manual:
If your web server does not allow you to do redirects, or the server does not have a way to communicate to the PHP binary that the request is a safely redirected request, you can specify the option --enable-force-cgi-redirect to the configure script. You still have to make sure your PHP scripts do not rely on one or another way of calling the script, neither by directly http://my.host/dir/script.php nor by redirection http://my.host/cgi-bin/php/dir/script.php.
Cheers
paulwratt@github