I have done URL filtering with .htaccess (using learning and generator), however I am still concerned that any POST request can be submitted to the PHP even there is only one POST form on the website, and it's not file upload.
I would like make Apache filtering file upload POST requests, so it never gets to PHP process.
I have just installed mod_security on Ubuntu 12 however at the moment I am clueless on how to do it properly.
This is to secure PHP from remote exploits using e.g. PHP file upload code, so in this case I would accept only POST with two fields: login and password, each has to be checked before reaching PHP that they are 16 characters long, there are no other variables etc.
Same for the Host: and Cookie, I would like to filter it the way that it blocks multiple remote exploits like SQL Injection etc.
The thing is that PHP always is processing data via POST and GET. If I could filter out the whole POST by a filter (which takes the header in, and then the rest of the stream in parts), I can make sure, that my login server is secure against PHP exploits.
I have login server like this:
/usr/bin/php5-cgi login 3844 0.0 2.2 159032 5520 ? S Jul18 0:00 /usr/bin/php5-cgi
It is confined with AppArmor, to isolate from other processes. Now my problem is that from this login server has all the tokens which are granting security to the all data. Now I need to make sure that the token is being given only with valid username and password, as well it's impossible to breach the with the most recent exploit being just developed on the next thread. Since this is only single REST call, it is very easy to filter only one POST request at the application level and maybe it would be even woth filtering it on another process, but this only creates more questions and no answers, because it's not easy to develop such server which will handle many connections, do safe checks and so on.
I run standard LAMP system and Fast-CGI, and all I want is to make the login secure.
Tokens are in MySQL database, as well logins and passwords. There are many logins and passwords, e.g. Host: field is used as login to obtain a random Cookie which grants access to website.
Login server creates the security schema for each user, which is copied to another servers, and used by MySQL to restrict data. So therefore I need to make it really extra secure because of PHP, and I got this previously abused in 100 possible ways.
The passwords are checked against dictionaries, so it's resilient to brute force.
Also Apache is restricted from getting MySQL access, it's the PHP with access, there is a password file and the secret key.
Also another thing is that I dont trust the PHP code, I need to assume it is backdoored, and there is also some remote shell lying around the sub folders, so I need to assume that only limited traffic comes to this server.
I dont want to put anything in front of it, as I already have firewall, router, and anything like this is very often easy to by-pass.
With some PHP running for 5 years unpatched, such filter would prevent a serious disaster, that the login page would be replaced with some malware, or something like this, as the login is meant to be secure, and actually prove that fact, that it is, and not because something else runs in front of it.
root@Login:/home/login# cat fcgi-bin/php5.fcgi
#!/bin/bash
PHPRC=$PWD/../etc/php5
export PHPRC
umask 022
export PHP_FCGI_CHILDREN
PHP_FCGI_MAX_REQUESTS=99999
export PHP_FCGI_MAX_REQUESTS
SCRIPT_FILENAME=$PATH_TRANSLATED
export SCRIPT_FILENAME
exec /usr/bin/php5-cgi
<VirtualHost 1.2.3.4:443>
SuexecUserGroup "#1000" "#1000"
ServerName login.admin.example.net
DocumentRoot /home/login/public_html
ErrorLog /var/log/virtualmin/login.admin.example.net_error_log
CustomLog /var/log/virtualmin/login.admin.example.net_access_log combined
ScriptAlias /cgi-bin/ /home/login/cgi-bin/
ScriptAlias /awstats/ /home/login/cgi-bin/
DirectoryIndex index.html index.htm index.php index.php4 index.php5
<Directory /home/login/public_html>
Options -Indexes +IncludesNOEXEC +FollowSymLinks +ExecCGI
allow from all
AllowOverride All
AddHandler fcgid-script .php
AddHandler fcgid-script .php5
FCGIWrapper /home/login/fcgi-bin/php5.fcgi .php
FCGIWrapper /home/login/fcgi-bin/php5.fcgi .php5
</Directory>
<Directory /home/login/cgi-bin>
allow from all
</Directory>
RemoveHandler .php
RemoveHandler .php5
IPCCommTimeout 31
FcgidMaxRequestLen 1073741824
SSLEngine on
SSLCertificateFile /home/login/ssl.cert
SSLCertificateKeyFile /home/login/ssl.key
</VirtualHost>
root@Login:/home/login# php -v
PHP 5.3.10-1ubuntu3.2 with Suhosin-Patch (cli) (built: Jun 13 2012 17:19:58)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
with XCache v1.3.2, Copyright (c) 2005-2011, by mOo
root@Login:/home/login# apache2 -V
Server version: Apache/2.2.22 (Ubuntu)
Server built: Feb 13 2012 01:51:50
Server's Module Magic Number: 20051115:30
Server loaded: APR 1.4.6, APR-Util 1.3.12
Compiled using: APR 1.4.5, APR-Util 1.3.12
Architecture: 64-bit
Server MPM: Prefork
threaded: no
forked: yes (variable process count)
Server compiled with....
-D APACHE_MPM_DIR="server/mpm/prefork"
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
-D APR_USE_SYSVSEM_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT=128
-D HTTPD_ROOT="/etc/apache2"
-D SUEXEC_BIN="/usr/lib/apache2/suexec"
-D DEFAULT_PIDLOG="/var/run/apache2.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_LOCKFILE="/var/run/apache2/accept.lock"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="mime.types"
-D SERVER_CONFIG_FILE="apache2.conf"