Come filtrare le richieste POST prima che raggiungano PHP su Apache?

2

Ho fatto il filtraggio degli URL con .htaccess (utilizzando l'apprendimento e il generatore), tuttavia sono ancora preoccupato che qualsiasi richiesta POST possa essere inviata al PHP anche se esiste solo un modulo POST sul sito web e non è il caricamento di file.

Vorrei fare in modo che il filtro Apache carica le richieste POST, quindi non arriva mai al processo PHP.

Ho appena installato mod_security su Ubuntu 12, ma al momento non ho idea di come farlo correttamente.

Questo serve per proteggere PHP da exploit remoti usando per es. PHP file upload code, quindi in questo caso accetterei solo POST con due campi: login e password, ognuno deve essere controllato prima di raggiungere PHP che siano lunghi 16 caratteri, non ci siano altre variabili ecc.

Uguale a Host: e Cookie, vorrei filtrarlo nel modo in cui blocca più exploit remoti come SQL Injection ecc.

Il fatto è che PHP sta sempre elaborando i dati tramite POST e GET. Se potessi filtrare l'intero POST tramite un filtro (che prende l'intestazione in, e poi il resto del flusso in parti), posso assicurarmi che il mio server di login sia sicuro contro gli exploit PHP.

Ho un server di login come questo:

/usr/bin/php5-cgi    login     3844  0.0  2.2 159032  5520 ?        S    Jul18   0:00 /usr/bin/php5-cgi

È limitato ad AppArmor, per isolare da altri processi. Ora il mio problema è che da questo server di login sono presenti tutti i token che concedono sicurezza a tutti i dati. Ora ho bisogno di assicurarmi che il token venga dato solo con username e password validi, così come è impossibile fare breccia con l'exploit più recente appena sviluppato sul thread successivo. Poiché si tratta di una sola chiamata REST, è molto facile filtrare solo una richiesta POST a livello di applicazione e forse sarebbe anche sufficiente filtrarla su un altro processo, ma questo crea solo più domande e nessuna risposta, perché non è facile sviluppare un server che gestirà molte connessioni, fare controlli sicuri e così via.

Eseguo il sistema LAMP standard e Fast-CGI, e tutto ciò che voglio è rendere sicuro il login.

I token sono nel database MySQL, come pure gli accessi e le password. Esistono molti accessi e password, ad es. Host: il campo viene utilizzato come accesso per ottenere un cookie casuale che consente l'accesso al sito Web.

Il server di login crea lo schema di sicurezza per ciascun utente, che viene copiato su un altro server e utilizzato da MySQL per limitare i dati. Quindi, per questo motivo, ho bisogno di renderlo davvero più sicuro grazie a PHP, e ho ottenuto questo in precedenza abusato in 100 possibili modi.

Le password vengono confrontate con i dizionari, quindi sono resistenti alla forza bruta.

Anche Apache non può accedere a MySQL, è il PHP con accesso, c'è un file password e la chiave segreta.

Un'altra cosa è che non mi fido del codice PHP, ho bisogno di presupporre che sia backdoor, e c'è anche qualche shell remota che giace intorno alle sottocartelle, quindi devo presumere che solo il traffico limitato arrivi a questo server.

Non voglio mettere nulla di fronte a questo, dato che ho già firewall, router e qualsiasi cosa come questa è molto spesso facile da bypassare.

Con alcuni PHP in esecuzione per 5 anni senza patch, tale filtro impedirebbe un grave disastro, che la pagina di accesso sarebbe stata sostituita con un malware, o qualcosa di simile, come il login è destinato a essere sicuro, e in realtà lo dimostrano , che è, e non perché qualcos'altro viene eseguito di fronte ad esso.

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"
    
posta Andrew Smith 19.07.2012 - 20:08
fonte

3 risposte

1

link

Permette di agganciare un comando esterno per leggere da stdin e scrivere su stdout.

Per il server di login è la soluzione ideale, quella piccola app C può semplicemente controllare l'intestazione (tramite l'ambiente) e il corpo, e spogliarla con tutto ciò che non corrisponde al pattern senza preoccuparsi con API Apache affatto, così come è molto più facile da fare, e l'overhead delle app C è molto basso rispetto a PHP.

    
risposta data 19.07.2012 - 22:55
fonte
3

Poiché il tuo obiettivo è fermare il codice prima che raggiunga il tuo script PHP, penso che il tuo corso migliore sia un Web Application Firewall .

Ma non penso che ne hai bisogno dalla tua descrizione. Sanitizing i tuoi input prevengono le cose che ti preoccupano, ma richiede lo script PHP elaborare i dati in entrata (dati POST, host, cookie).

    
risposta data 19.07.2012 - 20:35
fonte
0

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

Oltre alle altre risposte, Apache offre il < Limit > direttiva; questo consentirà di consentire solo determinati verbi HTTP (cioè GET, HEAD, ...) per directory. Potresti fare qualcosa come:

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

Questo farà sì che Apache impedisca alle richieste POST di raggiungere le tue pagine PHP. Anche se, quando dici:

Also another thing is that I dont trust the PHP code

Potresti avere problemi più grandi, un WAF è un buon modo per andare. Le backdoor possono usare le variabili GET tanto quanto le variabili POST.

    
risposta data 28.04.2014 - 07:45
fonte

Leggi altre domande sui tag