¿Inseguridad común en la configuración de PHP?

10

Trabajo con la administración de sistemas en una universidad y me topé con algo que probablemente es común, pero que me sorprendió bastante.

Todos los directorios public_html y las áreas web se almacenan en afs, con permisos de lectura para los servidores web. Dado que los usuarios pueden tener scripts php en su public_html, esto significa que pueden acceder a los archivos de los demás desde php (¡y los archivos web principales!).

Esto no solo hace que cualquier protección de contraseña .htaccess sea completamente inútil, sino que también permite a los usuarios leer archivos fuente php que contienen contraseñas de bases de datos mysql e información confidencial similar. O si encuentran que otras personas tienen directorios en los que los servidores web tienen acceso de escritura (por ejemplo, para registros personales o para guardar datos de formularios enviados) pueden almacenar archivos en esas cuentas.

Un simple ejemplo:

<?
  header("Content-type: text/plain");
  print file_get_contents("/afs/example.com/home/smith/public_html/.htpasswd"); 
?>

¿Es este un problema común? ¿Y cómo lo resuelves normalmente?

ACTUALIZAR:

Gracias por el aporte. Desafortunadamente, parece que no hay una respuesta simple. En un gran entorno compartido como este, los usuarios probablemente no deberían tener esta opción. El mejor enfoque que puedo pensar es establecer "open_basedir" en la configuración principal para todos los directorios "public_html", ejecutar suphp y solo permitir php limpio (sin scripts cgi, ejecutando comandos externos con backticks, etc.).

Sin embargo, cambiar la política de esta manera rompería muchas cosas y posiblemente haría que los usuarios agarren sus horcas y nos persigan ... Lo discutiré con mis colegas y lo actualizaré aquí si tomamos una decisión sobre cómo cambiar la configuración.

Ponto
fuente
Esta es una pregunta interesante. Estoy seguro de que los principales proveedores de alojamiento compartido (por ejemplo, DreamHost), esto no es posible. Pero me interesaría cómo protegen de esto. suphp, como se mencionó en cstamas, parece una buena solución, pero ¿es esto lo que usan la mayoría de los proveedores de hosting?
Lèse majesté
1
He usado la open_basedirsolución por debajo de la producción compartida sistemas de alojamiento, pero dividido cada uno en su propio host virtual - No estoy seguro de si funciona para directorios individuales ...
voretaq7

Respuestas:

8

Uno puede usar suphp que ejecuta el script php con el uid de su propietario.

http://www.suphp.org

cstamas
fuente
Esto probablemente no resolverá el problema anterior (al menos en un entorno de alojamiento compartido. Los archivos .htpasswd generalmente son propiedad del usuario propietario del sitio y grupo (apache) o mundo (porque los usuarios no conocen / no se preocupan por la seguridad) legibles, así que incluso con suphp podrían leer esos archivos)
voretaq7
@ voretaq7: se pueden aplicar varias otras restricciones. Por lo que recuerdo, incluso puedes negar el acceso a archivos que no te pertenecen. Entonces esto descarta el ataque anterior.
cstamas
Sé que puede restringir los permisos en los archivos ("No se puede escribir por grupo / otro / nadie"), pero no conozco una forma de bloquear las lecturas más allá de los permisos FS. Tienen check_vhost_docroot, pero que yo sepa que sólo se aplica a la secuencia de comandos se ejecuta (puedo estar equivocado en eso?)
voretaq7
1
No estoy seguro de si suphp es una buena solución en un entorno como este. Un usuario puede tener todo tipo de permisos que el usuario www no tiene. Un atacante que encontró un camino a través de php podría encontrar claves ssh o pestañas, o cambiar los scripts de inicio de sesión de los usuarios para crear puertas traseras. Y la configuración de "vhosts" no es tan útil ya que los directorios public_html están disponibles a través de "/ ~ username" en el host virtual principal. Estoy pensando que quizás los scripts en public_html deberían estar completamente deshabilitados.
Pontus
4

Mi sugerencia sería limitar el acceso de PHP a los archivos (a través de open_basedirdirectivas similares, por host virtual): desea que los usuarios puedan abrir / leer / escribir archivos debajo de su raíz web, y tal vez un nivel por encima (por cero espacio), pero no un directorio donde almacenarían, por ejemplo, htpasswdarchivos.

Una estructura de directorios como:

/Client
    /auth
    /site
        /www_root
        /www_tmp

Cumpliría con este requisito: open_basedirpodría señalarse de /Client/siteforma segura y los htpasswdarchivos almacenados /Client/auth(con .htaccessarchivos o httpd.confmodificados para apuntar a la ubicación adecuada).
Esto evita que sus clientes abran los archivos de otra persona, Y como beneficio, los usuarios malintencionados no pueden leer el contenido /Client/auth(o cualquier otra cosa en su sistema, como /etc/passwd:-)

Consulte http://php.net/manual/en/ini.core.php para obtener más detalles sobre la implementación de open_basedir y per-vhost.

voretaq7
fuente
1
suphpcomo lo señala cstamas también es una muy buena idea en un entorno de alojamiento compartido: hay un poco de sobrecarga para configurarlo, pero diría que la ganancia de seguridad vale totalmente la pena. A falta de sandboxing todos sus sitios PHP en algo como una cárcel de FreeBSD o una máquina virtual dedicada que es una de las mayores victorias de seguridad.
voretaq7
"open_basedir" parece ser una manera simple de separar los archivos web principales de los usuarios, siempre que "public_html" se sirva a través de su propio host virtual. Pero no protege a los usuarios entre sí, ya que no tienen sus propios hosts virtuales. ¿Derecho?
Pontus
No he intentado configurar open_basedirdentro de una directiva <Directory>, pero creo que debería ser permisible ("pruébalo y mira" - lo peor que puede hacer es no funcionar :)
voretaq7
1
Hasta ahora parece que open_basedir es lo que usan la mayoría de los servidores web comerciales (generalmente los suscriptores tienen sus propios dominios pagos o reciben un subdominio gratuito), pero para páginas de inicio basadas en directorios como en una institución académica, suphp parece ser la mejor respuesta.
Lèse majesté
1

No, no es un problema común porque la mayoría de los hosts compartidos definirían una configuración open_basedir en el archivo htaccess en el directorio public_html de cada usuario (o en el vhost si cada usuario tiene su propio vhost).

por ejemplo, archivo .htaccess:

# Assuming these are not set globally - its good practice to limit:
  php_flag magic_quotes_gpc off
  php_flag magic_quotes_runtime off
  php_flag register_globals off
  php_flag short_open_tag off
  php_value max_execution_time 60

# These set the user-specific paths
  php_value open_basedir /afs/example.com/home/smith:/usr/share/php/include
  php_value session.save_path /afs/example.com/home/smith/tmp
  php_value upload_tmp_dir /afs/example.com/home/smith/tmp

Pero asegúrese de establecer los permisos correctos en el archivo .htaccess para evitar que el usuario cambie open_basedir (si intenta anularlo en subdir / .htaccess, no debería funcionar, pero probablemente debería probar esto para asegurarse) .

HTH

C.

symcbean
fuente
2
Esto podría ayudar a ofrecer alguna protección inicial de nuevas cuentas. Pero el hecho de que un usuario no pueda editarlo puede hacer que sea tentador eliminar el archivo .htaccess (lo que puede hacer ya que solo requiere acceso de escritura al directorio public_html) y crear el suyo propio. Agregar un bloque "<Directory>" en la configuración principal para cada usuario funcionaría, pero aquí todavía pueden retroceder comandos externos desde php, lo que significa que open_basedir se elude fácilmente.
Ponto
@ Pontus: buen punto sobre la eliminación del archivo (no estoy seguro de si afs admite el atributo de archivo inmutable). Hubiera dado +1 si hubiera dicho que ejecutar el servidor web en la cárcel chroot protegería contra todo tipo de vulnerabilidades de ejecución del programa.
symcbean
1

AFS ignora los permisos simples de usuario de Unix. suPHP ejecuta un setuid antes de ejecutar el programa php, pero eso no le da al proceso los tokens kerberos necesarios para acceder a AFS y estar restringido a sus permisos. SuPHP tendría que modificarse de alguna manera para obtener esos tokens antes de que pudiera presentarse al sistema AFS como ese usuario. Que yo sepa, eso no se ha hecho. (De hecho, encontré esta pregunta al ver si alguien más lo había hecho).

Charles B
fuente