2

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"
8
  • What's bad that requests will reach PHP process? Jul 19, 2012 at 18:17
  • The PHP has to parse unfiltered user submitted data which can be used to run exploit and lead to information disclosure, which is the case for PHP file upload code now for 8 years. With filtered POST and GET I can secure PHP from the exploits like this. Jul 19, 2012 at 18:20
  • Do you want to filter POSTs or file uploads?
    – schroeder
    Jul 19, 2012 at 18:21
  • I want to filter POSTs, so e.g. I want only one kind of POST query to go thru, e.g. with just login and password fields, which must be alphanumeric and max 16 characters, and every other post to be rejected. Jul 19, 2012 at 18:21
  • Then sanitize the POST input on the scripts that need it? If your other PHP files don't process POSTS, then you're covered there. I'm still unsure what needs to be done.
    – schroeder
    Jul 19, 2012 at 18:24

3 Answers 3

3

Because your focus is stopping the code before it reaches your PHP script, I think your best course is a Web Application Firewall.

But, I don't think you need it from your description. Sanitizing your inputs will prevent the things you are concerned about, but it does require that the PHP script process the incoming data (POST data, hosts, cookie).

2
  • Many thanks! I uses few of them, but none of these actually did filtering of POSTs at that time. However I am looking to do it via little C code for Apache server. I could develop this but I am not sure what API to use, like mod_filter and how to compile / build so it reads the config from .htaccess file too Jul 19, 2012 at 19:12
  • mod_security defines itself as a Web Application Firewall May 21, 2013 at 19:59
1

http://httpd.apache.org/docs/2.2/mod/mod_ext_filter.html

Allows to hook external command to read from stdin and write to stdout.

For login server it is ideal solution, that small C app can simply check the header (via environment) and body, and strip it with everything what is not matching the pattern without bothering with Apache API at all, as well it is much easier to do, and C app overhead is very low compared to PHP.

1
  • I think if you actually measured it you'd find the overhead of starting a program, opening and closing the stdio streams and reaping the process is quite a big overhead (and needs to be done for every request) compared with running a couple of extra PHP instructions. Using mod_security or possible just mod_rewrite, it should be possible to detect uploads, even just using an autoprepend file ( if (count($_FILES)) exit; ) would be sufficient assuming your upload_tmp_dir is sufficiently isolated.
    – symcbean
    Oct 22, 2015 at 14:24
1

I would like make Apache filtering file upload POST requests, so it never gets to PHP process.

In addition to the other answers, Apache offers the <Limit> Directive; this will allow to you only allow certain HTTP verbs (i.e: GET, HEAD, ... ) per directory. You could do something like:

<Directory /var/www/site/unsafe>
  <Limit POST PUT DELETE>
    order deny,allow
    deny from all
  </Limit>
</Directory>

This will make Apache prevent the POST requests from reaching your PHP pages. Although, when you say:

Also another thing is that I dont trust the PHP code

You may have bigger problems, a WAF is a good way to go. Backdoors can use GET variables as much as POST variables.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .