Seguridad en Apache con rewrite y .htaccess

Bueno, no hay bien que por mal no venga, investigando como hacer funcionar mi script le he dedicado más tiempo al módulo rewrite.

Para el que no lo sepa como yo hace algún tiempo el  mod_rewrite es un módulo del servidor web Apache que a través de un .htaccess, reescribir urls.

Lo cuál nos da un número de posibilidades interesantes, por ejemplo direccionar las páginas de error a paginas personalizadas, además con esto, se ganan puntos en Google, para mejorar el posicionamiento de nuestra página, también permite ‘ocultar’ los parámetros que se envían de una página a otra, dificultando una posible inyección de SQL. Por ejemplo, una llamada que antes era:

http://adrianramirez.es/noticia.php?id=30

pasa a ser, por ejemplo:

http://adrianreamirez.es/listado_de_noticias/30

Todo esto conseguido gracias a un pequeño fichero .htaccess similar a este:

<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^listado_de_noticias/([0-9]+) noticia.php?id=$1 [L,NC]
</IfModule>

Como vemos, por un lado oculta la url original y por otro restringe mediante el .htaccess la entrada de parámetros, en este caso, el id sólo puede ser un número entre 0 y 9, por lo que no podremos escribir nada del estilo:

http://miweb.com/listado_de_noticias/30+and+1=1

Otro caso diferente sería cuando la inyección no se realiza en un valor numérico, por ejemplo:

RewriteRule ^listado_de_noticias/([a-zA-Z0-9]+) noticia.php?id=$1 [L,NC]

En este caso, nos permite introdudir números y letras, pero tampoco podríamos inyectar código SQL ya que ni el espacio ni las comillas están permitidos:

http://adrianreamirez.es/listado_de_noticias/titulo’+and+’1′=’1

En resumen, todo varía en función de cómo esté configurado el .htaccess, al que por supuesto no tenemos acceso. Pero eso no es todo. Muchos administradores piensan que con esto la web ya está protegida a ataques de inyección SQL pero realmente el mod_rewrite es sólo una máscara ya que si el fichero PHP final (noticia.php en este caso) tenía problemas de inyección, los seguirá teniendo. Y si alguien llega a averiguar el nombre del fichero original, podrá acceder directamente sin necesidad de pasar por el mod_rewrite.

Sólo hay que echarle un poco de imaginación. Por ejemplo, buscar nombres similares a ver si hay suerte. Si la url es  http://adrianreamirez.es/listado_de_noticias/30 se pueden realizar búsquedas a ver si hallamos la página original:

http://adrianreamirez.es/listado_de_noticias.php?id=30

http://adrianreamirez.es/noticias.php?id=30

http://adrianreamirez.es/noticias.php?idnoticia=30

…..

Aunque parezca un trabajo de chinos, muchas veces da resultado.

Y si el mod_rewrite se ha aplicado sólo por mantener la seguridad (o mejorar el posicionamiento) y no viene unido a un cambio de estética o remodelación de la web, lo más probable es que podamos encontrar el nombre de algún fichero original mediante otras técnicas, por ejemplo:

  • Buscando en Google y demás buscadores un listado de las páginas indexadas de esa web, con la búsqueda:  ‘site:miweb.com inurl:.php’. Esto nos puede mostrar páginas antiguas que aún sigan indexadas.
  • Buscando con un spider el contenido de cada página de la web. Muchas veces se olvida cambiar una URL para que apunte a la nueva dirección en lugar de al fichero PHP
  • Buscando en Google enlaces hacia esa web, donde es posible que un link antiguo apunte a una noticia o cualquier otra sección de la web, con la búsqueda: ‘link:miweb.com’ o bien: site:.com “miweb.com” -site:miweb.com
  • Buscando en WayBack Machine, que guarda un histórico de muchísimas webs (150 billones … casi nada jeje) y además suele guardar una captura de toda la web cada mes, por lo que muy probablemante escontremos la estructura antigua.

Configurando .htaccess para proteger nuestro servidor.

Aquí os dejo varios tips. Fruto del tiempo libre y sin mujer que lo ocupe:

Tip1:
Bloquear a los Bot’s mas conocidos para evitar el consumo innecesario de ancho de banda

tip2:

Si no nos gusta que nos visiten desde un proxy,  lo que hace es simple detecta a un visitante que proviene de un servidor proxy y lo que hace es darle un white screen

 

#Simple .htaccess Proxy Blocker Mod
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP:VIA}       !^$ [OR] RewriteCond %{HTTP:FORWARDED}   !^$ [OR] RewriteCond %{HTTP:USERAGENT_VIA}  !^$ [OR] RewriteCond %{HTTP:X_FORWARDED_FOR}  !^$ [OR] RewriteCond %{HTTP:PROXY_CONNECTION}  !^$ [OR] RewriteCond %{HTTP:XPROXY_CONNECTION}  !^$ [OR] RewriteCond %{HTTP:HTTP_PC_REMOTE_ADDR} !^$ [OR] RewriteCond %{HTTP:HTTP_CLIENT_IP}      !^$
RewriteRule ^(.*)$ - [F] </IfModule>
#Simple .htaccess Proxy Blocker Mod

——————————————————————————-

tip3:

clasico LimitRequestBody; su función es simple, lo que hace es limitar «tanto la descarga como la subida» en cantidad de kilobytes.

#1 megabyte
LimitRequestBody 1024
#10 megabytes
LimitRequestBody 10240
#100 megabytes
LimitRequestBody 102400

—————————————————————

Tip4:

Options All -Indexes evitara que se listen tus archivo cuyas carpetas no tengan index(trabaja de la mano con ErrorDocument)

Options All -Indexes

Caso de IndexIgnore * e comprobado que perjudica de cierta manera al SEO, por lo cual prefiero utilizarlo de esta manera IndexIgnore *. extensión, siguiendo el ejemplo anterio

IndexIgnore *.swf

bloqueo la indexacion de todos los archivos swf, tanto del directorio y sub-directorios, donde se aloje el .htaccess

—————————————————————————

Tip5:

Evitando el intento de manipulación malintencionada de la URL evitaremos La solicitud de método, que se suministra en el REQUEST_METHOD , Si el script en este caso del atacante intenta hacer peticiones por el método que no admitimos deberá ser rechazarlo con un error.

#para nuestro ejemplo solo intentaremos que no se visualice nada
#es decir aremos un white screen (pantallita blanca), como siempre aremos una sola consulta usando un array

RewriteCond %{REQUEST_METHOD} ^(HEAD|TRACE|DELETE|TRACK) [NC] RewriteRule ^(.*)$ - [F,L]

———————-

o también puedes optar por darle algo visual de que su intento «tan primitivo» de hacking no tuvo exito agregando una ruta hacia un archivo o imagen cual sea el caso .

RewriteCond %{REQUEST_METHOD} ^(HEAD|TRACE|DELETE|TRACK) [NC] RewriteRule ^(.*)$ http://midominio.com/intento-de-requets.php  [F,L]

—————————————————

Explicaré por que  solo se usa 4 métodos de los que muchos que hay.
HEAD = evitar requets de la cabeceras
TRACE = evitemos que nos escaneen el sitio, para los veteranos programando en consola como yo, es como utilizar un print trace, para debugear código (en este caso seria pintar un mapa de tu sitio web)
DELETE = su mismo nombre lo dice es mas que obvio :S
TRACK = son métodos HTTP que se utilizan para depurar las conexiones del servidor web Se ha demostrado que los servidores que soportan este método están sujetos a ataques a través de secuencias de comandos del sitio, llamado XST «Cross Site Tracing», son deficientes en los navegadores. especialmente en el mozilla «ups creo que ese dato no lo debí de dar»
Un atacante puede utilizar este error para engañar a los usuarios de una web con el propósito de apoderar se de credenciales(datos importantes). Solución Viable: Des-habilitar estos métodos.

————————————————————————–

TIP (perdí la cuenta)

Mostrar un error HTTP de una manera amigable al visitante (para nuestro ejemplo solo usaremos los mas comunes)

ErrorDocument 401 /errorpage401.php
ErrorDocument 404 /errorpage404.php
ErrorDocument 403 /errorpage403.php
ErrorDocument 500 /errorpage500.php

——————-

Tip7:

Evitar esos desagradables errores de php que tan mala imagen dan a nuestras web o las de nuestros clientes con una de las lineas de código que mas me gusta, cuya función es la de deshabilitar la visualización de todos los errores, no recomendable en modo de desarrollo.

php_flag display_errors off

———————————————————————————————————

Tip8:

# Protegerse contra los ataques DOS limitando el tamaño de subida de archivos
LimitRequestBody 10240000

Tip9:

Tip10:

# Evitar escaneos y cualquier intento de manipulación malintencionada
# de la URL. Con esta regla es imposible lanzar ataques de inyección (SQL, XSS, etc)
RewriteCond %{HTTP_USER_AGENT} ^$ [OR]
RewriteCond %{HTTP_USER_AGENT} ^(-|.|’) [OR]
RewriteCond %{HTTP_USER_AGENT} ^(.*)(<|>|%3C|%3E)(.*) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(java|curl|wget)(.*) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(.*)(libwww-perl|libwwwperl|snoopy|curl|wget|winhttp|python|nikto|scan|clshttp|archiver|loader|email|harvest|fetch|extract|grab|miner|suck|reaper|leach)(.*) [NC,OR]

RewriteCond %{REQUEST_URI} ^(/,|/;|/<|/>|/’|/`|/%2C|/%3C|/%3E|/%27|/////) [NC,OR]
RewriteCond %{HTTP_REFERER} ^(.*)(%00|%08|%09|%0A|%0B|%0C|%0D|%0E|%0F|%2C|<|>|’|%3C|%3E|%26%23|%27|%60)(.*) [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)(%00|%08|%09|%0A|%0B|%0C|%0D|%0E|%0F|%2C|%3C|%3E|%27|%26%23|%60)(.*) [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)(‘|-|<|>|,|/|\\|\.a|\.c|\.t|\.d|\.p|\.i|\.e|\.j)(.*) [NC,OR]
RewriteCond %{HTTP_COOKIE} ^(.*)(<|>|’|%3C|%3E|%27)(.*) [NC]
RewriteRule ^(.*)$ error.php [NC]

 

Otra cosa:

Explicación de lo más básico sobre el módulo rewrite, se que debería de ir al principio, pero bueno:

La sintaxis de RewriteCond es como sigue:

STRING debe ser una variable del servidor o una referencia anterior a alguna RewriteCond.
CONDITION puede ser una expresión regular, similar a una RewriteRule. Además puede tener variantes especiales sobre las expresiones regulares estándar.

Cómo encaja todo esto en nuestas RewriteRule? Si colocas un RewriteCond antes de RewriteRule, la RewriteRule sólo se procesará cuando la RewriteCond sea evaluada como true (esto es, si se cumple la CONDITION).

Y ya vale de teoría. Hagamos algo práctico para evitar que ciertas direcciones IP accedan a nuestro servidor.

Es un ejemplo bastante simple. Si la IP del visitante es 123.45.67.89, a éste se le muestra una página de baneo.

 

 

Un pensamiento en “Seguridad en Apache con rewrite y .htaccess

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *