Cómo asegurar un directorio en Apache usando una sesión PHP

8

Tengo un sitio que usa sesión PHP para autenticación. Hay un directorio al que me gustaría restringir el acceso al que no usa PHP, solo está lleno de contenido estático.

Simplemente no sé cómo restringir el acceso sin que cada solicitud pase por un script PHP. ¿Hay alguna forma de hacer que Apache verifique las credenciales de la sesión y restrinja el acceso como la autenticación básica?

Cogsy
fuente

Respuestas:

5

A menos que haya cambiado la configuración, los datos de sesión de PHP se almacenan en una variación en su propio formato de serialización () en un directorio temporal, y no es fácil llegar a eso sin usar PHP.

desafortunadamente, parece querer la velocidad de los archivos estáticos servidos al tiempo que autoriza dinámicamente cada solicitud, que no son objetivos realmente compatibles. Puede comprimir al tener un script PHP súper ligero que luego usa mod_rewrite para reescribir las solicitudes a los archivos dentro de él, que pasa por cosas que están bien. Ejemplo super simple:

.htaccess:

 RewriteEngine On
 RewriteMap auth prg:auth.php
 RewriteRule (.*) ${auth:$1}

auth.php:

#!/usr/bin/php
 <?PHP
 set_time_limit(0); # This program needs to run forever. 
 $stdin = fopen("php://stdin","r"); # Keeps reading from standard in
 while (true) {
        $line = trim(fgets($stdin));
        if (isset($_SESSION['USER_LOGGED_IN'])) {
                echo $line\n";
        } else {
                echo "authfailed.html\n";
        }
 }

en particular, ese script PHP se ejecuta para siempre, por lo que necesitará reiniciar apache si lo cambia, creo.

Todo esto no ha sido probado, pero esa es aproximadamente la dirección en la que creo que tendrías que ir.

Referencias

Acuario
fuente
Me gusta este enfoque, pero me pregunto si un script RewriteMap tiene acceso a otra cosa que no sea stdin. ¿Tiene el contexto de cookies, etc.?
Cogsy
En realidad, sí, tienes un punto. Puede enviar el valor de las cookies utilizando la sintaxis de variables de entorno de mod_rewrite (así que creo que la sintaxis se convertiría en algo así como $ {auth: $ 1 $ COOKIES} y tendría que dividir la línea de stdin por argumentos, por este método podría recoger el contenido de la sesión.
Aquarion
¿Qué sucede si configura una cookie al iniciar sesión con una identificación de autenticación constante (mucha longitud de bits) y la verifica mediante el acceso al directorio? No es la mejor solución, pero puede funcionar en páginas de administración ... (Por páginas de compartir archivos no funciona porque los usuarios pueden compartir la cookie ...)
inf3rno
1

Si tenía una cookie en particular que puede esperar, puede probar su ausencia con mod_rewrite y dar un 403 Prohibido.

RewriteCond %{HTTP_COOKIE} !LoggedIn=true
RewriteRule .* - [F,L]

Pero, si alguien supiera que necesitaban un conjunto de cookies con "LoggedIn = true", entonces podrían evadir fácilmente su "protección".

Una sesión PHP es específica de PHP. Apache no tiene forma de usar ninguna información en una sesión PHP. Tendría que tener algún módulo de autenticación específicamente para hacer la verificación de la sesión.

Lo que he visto hacer a la mayoría de las personas es que un script PHP maneje la publicación del contenido estático en el sentido de que recibe la solicitud, verifica la sesión, lee el archivo y envía el contenido con la información MIME adecuada.

Rugmonster
fuente
O puede modificar el archivo .htaccess con cada inicio de sesión, cierre de sesión y gc ...
inf3rno
1

La solución convencional para ese problema es redirigir cada llamada en esa carpeta a un archivo php, que verifica los permisos del usuario, y luego lee el archivo y lo envía a la secuencia de salida o redirige al usuario a "sin permiso" sitio. Por ejemplo...

Otra forma complicada de proteger sus archivos es generar un token desde session_id y una sal estática (y opcionalmente desde la ruta del archivo estático), y verificarlo mediante el acceso al archivo. Por lo tanto, debe regenerar ese token en su archivo htaccess. No sé si es posible solo con .htaccess, o si tienes que usar php para eso. Encontré una solución similar aquí. Estoy 99% convencido de que el md5 no es una función de reescritura de mod incorporada.

inf3rno
fuente
1
Me encanta la idea del enlace Blogspot para usar RewriteMapen un prg://…recurso de script de shell que realiza todo el cifrado y verificación MD5 real. Necesito probar esto y asegurarme de que funcione en mi configuración, pero parece que debería funcionar con Apache + el módulo mod_rewrite.
Thirdender
1

Mi plan para resolver este problema ahora es

  1. Redireccionar la solicitud a PHP

    RewriteEngine on
    RewriteRule ([0-9a-z-_]+)$ authenticateUser.php?&file=$1 [L]
    
  2. Autentique al usuario en PHP (todos los demás métodos de autenticación pueden ser demasiado débiles o requieren escritura en archivos todo el tiempo)

    if ( User::hasPermission() && isSane( $filePath ) ) {
        // 
        header( 'X-Sendfile: ' . $filePath );
    }
    
  3. Usa Apache's mod_xsendfile( docs , github )

Rainer Rillke
fuente