Los aspectos de seguridad tienen una importante componente técnica que no podemos ovbiar. Lo que sigue intenta brindar algunas pistas.

Con la sencillez que ofrecen hoy día los instaladores de los sitios Web de administración de contenido (CMS como Joomla, Moodle, WordPress, etc.) es muy común que, una vez que ha finalizado la instalación, el interesado sólo se dedique a cargar su propia información y configurar las opciones (más que abundantes) con lo que, en realmente poco tiempo, se puede tener un importante y profesional sitio Web.

Sin dudas, el uso de estas aplicaciones es tentador por su facilidad de instalación, potencia, variedad de opciones e importantes herramientas que brindan a administradores y usuarios un sinnúmero de ventajas. La eficiencia del lado del usuario, y aún del administrador-Webmaster, es comprobada.

Sin embargo, la contraparte no es tan alegre ya que, normalmente, para poder iniciar o completar la instalación, el mismo proceso indica que ciertos directorios deben tener acceso total (0777) al igual que algún que otro archivo de configuración, lo que debe ser llevado a cabo si se quiere instalar el sistema, desde ya. Una vez finalizada la instalación y, al ingresar por vez primera al sistema desde la Web, en algunos casos (¡los menos!) se previene sobre la situación de modo que la persona pueda asignar relativa seguridad a su sitio Web y al resto de los usuarios que comparten un mismo servidor o unidad.

¿Por qué es tan riesgosa la situación?

Un directorio con acceso total (0777) significa TRES cosas desde el lado de un visitante anónimo por medio de la Web:

1) Puede LEER el contenido de un directorio

2) Puede ESCRIBIR en el directorio (se puede no sólo subir nuevos archivos sino romper o sobrescribir los actuales con el consiguiente daño que ello pueda generar a la funcionalidad de su sitio Web)

3) Puede EJECUTAR lo que se haya subido o modificado.

El punto esencialmente peligroso, como se dará cuenta, es el último.

Es importante notar que la gran mayoría de la gente que sube imágenes hace sólo eso: sube una foto. No intenta romper ni hackear un sitio Web.

El problema se suscita cuando alguien o, mejor dicho, un sistema de monitoreo de determinados CMS o tipos de instalaciones, encuentra un directorio con acceso total: sube lo que necesite para sus propósitos y ¡voila! lo ejecuta. Puede ejecutar un script o sistema para mandar spam desde su dominio; puede intentar propagar troyanos; puede poner en marcha un sistema de PHISHING (conocidos como sistemas para el robo de identidad personal sensible y confidencial) o puede sólo querer dejar su “huella” sobre su pseudo-capacidad (que no habría sido posible sin un acceso global que muy sencillamente se lo ha permitido).

Ahora bien. Si un sitio necesita que los visitantes suban imágenes y de un script que trabaje sobre ellas (creación de miniaturas, resampleos, etc.) necesitará de permisos 0777.

La pregunta que debemos hacernos salta a la vista:

¿Cómo mantener la funcionalidad y no descuidar la seguridad del sitio Web?

Intentaré brindar posibles respuestas.

Algunas sugerencias para mitigar el conflicto

Existen muchas opciones a la hora de asegurar un sitio Web.

Algunas son llevadas a cabo a un nivel interno por parte de nuestra empresa por lo que podemos hacer frente a los miles de intentos a los que un servidor en Internet es afectado cada día… sí, ¡miles al día!

Para comprobarlo y a simple modo ilustrativo, busque “joomla hacking” (recuerde: Joomla es el nombre de un administrador de contenido muy conocid, puede buscar por otro si lo desea) en GOOGLE y verá importante cantidad de enlaces que evidencian la situación.

Veamos las opciones:

Primer caso: acceso global FUERA de public_html

En lo personal, cada vez que necesito un directorio con permisos global (0777), lo pongo al MISMO NIVEL que public_html y no DENTRO de public_html. IMPORTANTE: Nunca asigne permiso 0777 al directorio public_html

Cuando un visitante ingresa a su sitio Web de la forma www.ejemplo.com, está ingresando al servidor que aloja su cuenta y a una estructura que es algo así cómo: /home/ejemplo/public_html. Es particular accede a un archivo del tipo index.html o index.php quedando así el acceso real: /home/ejemplo/public_html/index.html o /home/ejemplo/public_html/index.php

En nuestro ejemplo, y desde la Web, NO se tiene acceso a /home/ejemplo ya que el mismo servidor Web se encarga de “rutear” TODOS los accesos al directorio antes mostrado: /home/ejemplo/public_html

Si se pone una carpeta con acceso global en /home/ejemplo/fotos es inaccesible desde la Web debido a que NO SE PUEDE ir hacía atrás desde la ubicación BASE que es: /home/ejemplo/public_html. No hay manera.

En éste escenario, el directorio fotos está protegido a pesar de tener acceso global debido a la naturaleza misma del servidor Web y no a un principio de seguridad que puede implementarse.

La ventaja queda clara aunque tiene una complejidad que no resulta muy cómoda de implementar: es necesario un script que sepa subir archivos fuera de la estructura accesible desde la Web. Si bien es para nada complejo, implementarlo puede resultarle en un cierto dolor de cabeza. Si le interesa, puedo brindarle algún script a modo de ejemplo. Su uso es libre (GNU).

Segundo Caso: DENEGAR ejecución de todo tipo de archivo MENOS de imágenes

En éste escenario UD. tiene un directorio como el que sigue (a modo de ejemplo siempre): /home/ejemplo/public_html/images

Para que sólo se vean los archivos de imágenes del tipo que desee (jpeg, jpg, gif, etc.), deberá crear un archivo que llamará así: “.htaccess” (el punto inicial es importante) y lo subirá al directorio que tiene las imágenes (/home/ejemplo/public_html/images en nuestro ejemplo)

El contenido del archivo es el que sigue:

# ————————————————————–
# DIRECTIVAS GENERALES
# ————————————————————–
# Evitar acceso por el navegador a una carpeta sin “index”:
Options All -Indexes

# Evitar el listado de directorios:
IndexIgnore *

# Evitar EXEC de scripts
RemoveHandler cgi-script .pl .py .cgi

# ————————————————————–
# No permitir ningún tipo de archivo
# ————————————————————–
<Files *>

# Primero controlaremos las directivas ALLOW y luego DENY
# Significa que debemos especificar TODO lo que permitiremos explicitamente.
Order allow,deny

# Si una directiva ALLOW se cumple, el acceso es concedido (en el presente bloque).

# Si ninguna directiva ALLOW se cumple, se examinan las directivas DENY

# Al ser DENY la directiva que se examina al final, debemos poner todo lo que
# deseemos denegar o nada para que se tome el default de
# la directiva que es: FROM ALL (denegar a todos los orígenes)

# Al NO permitir el acceso desde ningún host o IP al contenido del directorio actual
# (y todos los que se encuentran dentro de éste), no es necesario especificar la
# directiva DENY ya que se toma el default: a todos (FROM ALL)
# Deny from all

</Files>

# ————————————————————–
# Sólo permitir estos tipos de archivos
# ————————————————————–
<FilesMatch “\.(jpeg|jpg|swf|png|xml|gif|ico|html)$”>

# Si se ingresó a este bloque, es que se trata de un tipo de archivo (extension o
# parte final del mismo) permitido (por el FilesMatch)

# Primero controlaremos las directivas ALLOW y luego DENY
# Significa que debemos especificar TODO lo que permitiremos explicitamente.
order allow,deny

# Como se trata de un Order que tiene por default a denied, debemos indicar una
# directiva del tipo ALLOW.  Si se quita la linea que sigue, es denied por default
# (tal lo que se acaba de explicar)
allow from all

</FilesMatch>

# ————————————————————–
# Lo que sigue es a los solos efectos demostrativos y es totalmente equivalente a la
# sección anterior salvo por el esquema de control de las directivas Allow y Deny
# que es el inverso.
# SOLO PERMITIR ESTOS TIPOS DE ARCHIVOS
# ————————————————————–
<FilesMatch “\.(jpeg|jpg|swf|png|xml|gif|ico|html)$”>

# Primero se controlan las directivas DENY y luego ALLOW
# Significa que debemos TODO lo que NO se permite y, sino, es concedido el
# acceso por default
order deny,allow

# Como se trata de un Order que tiene por default el permitir el acceso, NO es necesario
# dar mayores detalles por lo que no es necesaria una directiva ALLOW: allow from all

</FilesMatch>

Sólo es necesario que lo agregue en el directorio protegido. Si, por ejemplo, dentro del directorio con acceso global de nuestro ejemplo (/home/ejemplo/public_html/images) tiene otro directorio también con acceso global (digamos: /home/ejemplo/public_html/images/files) NO necesita ponerlo dentro del directorio “files” ya que se toma la configuración del anterior. De todos modos, si lo copia en todos y cada uno de los directorios con acceso global (0777) no hay problema. Funciona igual.

Con éste archivo NO se impide que se suba NINGÚN tipo de archivo al directorio comprometido, sólo se impide que se EJECUTEN otros archivos que no sean los tipos de imágenes especificados (pueden ser los tipos de archivos que desee).

No es una solución realmente segura en su totalidad debido a que varias vulnerabilidades han sido explotadas por medio de imágenes especialmente preparadas. La ventaja es que no son muy frecuentes los ataques desde imágenes ya que los sistemas de búsqueda prefieren no complicarse y van detrás de sitios sin protección alguna. Piense que son sistemas que corren en modo automático las 24 horas y que avisan al “dueño” si se pudo entrar. Si se encuentran con una traba como la descrita cambian de dominio (casi siempre) salvo que alguien quiera dañarle puntualmente.

Una consideración final

La seguridad de un sitio Web debe ser mantenida entre ambas partes: prestador del servicio y cliente.

El proveedor de hosting debe contemplar las correspondientes actualizaciones de seguridad, upgrades de servicios y demás aspectos ligados a la seguridad de servidores que utilice (ej: modsecurity en Apache)

La parte del cliente puede resultar compleja o no, dependiendo de sus conocimientos, pero independientemente de ello, es necesario invertir tiempo en el tema seguridad de un sitio Web. El medio lo requiere. Internet no está libre de personas mal intencionadas que intentarán utilizarla para fines personales y, muy a menudo, con delictivos propósitos.

Reciban un cordial saludo,

Julio Alfredo Botto
www.sectorhosting.com

Adenda (por la implementación de Suexec):

Si se ha activado el módulo suExec y PHPsuExec, deberá asignar el permiso 775 en lugar de 777 cuando requiera accesibilidad global. De no hacerlo, se recibirán errores 500 (Internal Web Server Error) que indican la asignación inválida de un permiso en un script CGI o PHP.

© 2010 SectorHosting BLOG Suffusion WordPress theme by Sayontan Sinha