¿Cómo filtrar las solicitudes POST antes de que lleguen a PHP en Apache?

2

He hecho el filtrado de URL con .htaccess (usando learning y generator), sin embargo, todavía me preocupa que cualquier solicitud POST pueda enviarse al PHP aunque solo haya un formulario POST en el sitio web, y no se cargue el archivo.

Me gustaría hacer que las solicitudes POST de carga de archivos de filtrado de Apache, para que nunca lleguen al proceso PHP.

Acabo de instalar mod_security en Ubuntu 12, sin embargo, en este momento no tengo idea de cómo hacerlo correctamente.

Esto es para proteger PHP de vulnerabilidades remotas usando, por ejemplo, Código de carga de archivos PHP, por lo que en este caso solo aceptaría POST con dos campos: inicio de sesión y contraseña, cada uno debe verificarse antes de llegar a PHP para que tengan 16 caracteres, no hay otras variables, etc.

Lo mismo para el host: y la cookie, me gustaría filtrarlo de forma que bloquee múltiples explotaciones remotas como la inyección SQL, etc.

Lo que pasa es que PHP siempre está procesando datos a través de POST y GET. Si pudiera filtrar todo el POST por un filtro (que toma el encabezado y luego el resto de la secuencia en partes), puedo asegurarme de que mi servidor de inicio de sesión está seguro contra las vulnerabilidades de PHP.

Tengo un servidor de inicio de sesión como este:

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

Se limita a AppArmor, para aislarlo de otros procesos. Ahora mi problema es que desde este servidor de inicio de sesión tiene todos los tokens que otorgan seguridad a todos los datos. Ahora necesito asegurarme de que el token se entregue solo con un nombre de usuario y una contraseña válidos, y es imposible violarlo con el exploit más reciente que se acaba de desarrollar en el siguiente hilo. Dado que esta es solo una llamada REST, es muy fácil filtrar solo una solicitud POST en el nivel de la aplicación y tal vez sería incluso lo mismo filtrarlo en otro proceso, pero esto solo crea más preguntas y no respuestas, porque no es fácil Desarrolle un servidor que maneje muchas conexiones, realice comprobaciones de seguridad, etc.

Ejecuto el sistema LAMP estándar y Fast-CGI, y todo lo que quiero es hacer que el inicio de sesión sea seguro.

Los tokens están en la base de datos MySQL, así como los inicios de sesión y las contraseñas. Hay muchos inicios de sesión y contraseñas, por ejemplo. Host: el campo se utiliza como inicio de sesión para obtener una cookie aleatoria que otorga acceso al sitio web.

El servidor de inicio de sesión crea el esquema de seguridad para cada usuario, que se copia en otros servidores y MySQL usa para restringir los datos. Por lo tanto, necesito hacer que sea realmente seguro gracias a PHP, y me abusaron de esto de 100 maneras posibles.

Las contraseñas se comparan con los diccionarios, por lo que es resistente a la fuerza bruta.

También Apache tiene restringido el acceso a MySQL, es PHP con acceso, hay un archivo de contraseña y la clave secreta.

Otra cosa es que no confío en el código PHP, debo asumir que está en la puerta trasera, y también hay algo de shell remoto en las subcarpetas, así que debo asumir que solo el tráfico limitado llega a este servidor.

No quiero poner nada delante, ya que ya tengo firewall, enrutador, y todo esto es muy fácil de evitar.

Con algunos PHP ejecutándose durante 5 años sin parchear, dicho filtro evitaría un desastre grave, la página de inicio de sesión se reemplazaría con algún malware, o algo así, ya que el inicio de sesión debe ser seguro y, de hecho, demostrarlo. , eso es, y no porque algo más corra delante de él.

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"
    
pregunta Andrew Smith 19.07.2012 - 20:08
fuente

3 respuestas

1

enlace

Permite enganchar un comando externo para leer desde la entrada estándar y escribir en la salida estándar.

Para el servidor de inicio de sesión es la solución ideal, esa pequeña aplicación de C puede simplemente verificar el encabezado (a través del entorno) y el cuerpo, y eliminarlo con todo lo que no coincida con el patrón sin molestar en absoluto a la API de Apache, como es mucho más fácil de hacer, y la sobrecarga de la aplicación C es muy baja en comparación con PHP.

    
respondido por el Andrew Smith 19.07.2012 - 22:55
fuente
3

Debido a que su enfoque es detener el código antes de que llegue a su script PHP, creo que su mejor curso es un Firewall de aplicaciones web .

Pero, no creo que lo necesites de tu descripción. La desinfección de sus entradas evitará las cosas que le preocupan, pero requiere que el script PHP procesar los datos entrantes (datos POST, hosts, cookies).

    
respondido por el schroeder 19.07.2012 - 20:35
fuente
0
  

Me gustaría que las solicitudes POST de carga de archivos de filtrado de Apache, por lo que   nunca llega al proceso de PHP.

Además de las otras respuestas, Apache ofrece el < Limit > Directiva ; esto le permitirá solo permitir ciertos verbos HTTP (es decir, GET, HEAD, ...) por directorio. Podrías hacer algo como:

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

Esto hará que Apache impida que las solicitudes POST lleguen a sus páginas PHP. Aunque, cuando dices:

  

Otra cosa es que no confío en el código PHP

Es posible que tengas problemas más grandes, un WAF es un buen camino a seguir. Las puertas traseras pueden usar variables GET tanto como variables POST.

    
respondido por el ndrix 28.04.2014 - 07:45
fuente

Lea otras preguntas en las etiquetas