2010-08-12 19 views
8

Estoy usando un plan de alojamiento web GoDaddy en una plataforma Windows. Esta no fue mi elección, tiene que ver con una parte diferente del sitio real que usa ASP.NET (tampoco es mi elección).Restringir el acceso a los archivos - solo leer a través de PHP

Tengo una base de datos SQL con un montón de entradas con información no confidencial del cliente. La clave principal en esto es un entero de AutoIncrement, y tengo una serie de archivos PDF que coinciden con cada uno de esos enteros (por ejemplo, 555.pdf, 7891.pdf, etc.).

Mi objetivo es restringir el acceso directo a estos archivos, quiero que los usuarios tengan que pasar primero por un proceso de búsqueda e inicio de sesión (PHP). Originalmente, planeé colocar los archivos sobre la carpeta PUBLIC_HTML, pero GoDaddy se niega a darme acceso a la raíz sin un servidor dedicado ($ 20 por mes a partir de ellos).

Lo siguiente que revisé fue HTACCESS. Iba a restringir el acceso a los archivos solo a los scripts PHP al permitir el acceso a la dirección IP del servidor (o localhost/127.0.0.1). Lamentablemente, esto no funciona porque GoDaddy no ejecuta Apache en sus servidores de Windows.

Podría poner los archivos en BLOB en la base de datos, pero eso se pone realmente complicado cuando necesito trabajar con ellos rápidamente (además he tenido algunos problemas con ese enfoque).

¿Alguna sugerencia para restringir el acceso a los archivos solo a un script PHP (readfile())?

+0

Eso dependerá del servidor web que estén usando (IIS, supongo). Tal vez deberías etiquetar esto con IIS. – Artefacto

Respuesta

5

Dado que no se puede poner los archivos en cualquier lugar pero en su directorio public_html, que tendrá que ir a por el temido/odiado "seguridad por oscuridad" método

  1. Crear un subdirectorio de nombre aleatorio para almacenar los archivos en: public_html/RANDOMGARBAGE

  2. Asegúrese de que el directorio no se pueda explorar. Deshabilite la exploración de directorios (si puede) y coloque un documento predeterminado (index.html?) También, de modo que aunque esté activada la exploración, no obtendrá la lista de directorios.

  3. No guarde sus archivos con nombres imaginables. En lugar de almacenarlos con la ID de la base de datos, guárdelos con un nombre salado + hash en su lugar: $crypted_filename = sha1($real_filename . 'some hard-to-guess salt text'); (por supuesto, haga esto más complejo si es necesario). Almacene el nombre de archivo original en su base de datos. Así que terminan con algo como:

    public_html/RANDOMGARBAGE/5bf1fd927dfb8679496a2e6cf00cbe50c1c87145 public_html/RANDOMGARBAGE/7ec1f0eb9119d48eb6a3176ca47380c6496304c8

  4. servir los archivos a través de un script PHP - Nunca vincular al nombre del archivo hash directamente

    Descargar

que luego hace:

<?php 

    $fileID = (int)$_GET['fileID']; 

    $crypted_file = sha1($fileID . 'some hard-to-guess salt text'); 

    $full_path = 'public_html/RANDOMGARBAGE/' . $crypted_file; 
    if (is_readable($full_path)) { 
     if(user_is_allowed_to_see_this_file()) { 
      /// send file to user with readfile() 
      header("Content-disposition: attachment; filename=$ORIGINAL_FILENAME"); 
      readfile($full_path); 
     } else { 
      die("Permission denied"); 
     } 
    } else { 
     /// handle problems here 
     die("Uh-oh. Can't find/read file"); 
    } 

De esta manera el usuario nunca ver lo que su nombre de archivo "s00per seekrit" es, ellos sólo ven su navegador golpeó ...php?fileID=37 y empezar una descarga de secret file.pdf

Además de esto, puede en ocasiones cambiar el nombre del sub-especial directorio a otra cosa de forma regular, así como cambiar el texto saliente (que luego requiere que actualice todos los nombres de archivo hash con los nuevos valores sha1).

0

Simplemente puede ocultarlos. Es la seguridad a través de la oscuridad, pero parece ser tu mejor opción si no puedes mantenerlos fuera de la raíz web, o encontrar la manera de decirle al servidor que no los atienda directamente.

Así que ellos se adhieren en algún directorio nombre aleatorio:

asd8b8asd8327bh/123.pdf 
asd8b8asd8327bh/124.pdf 
asd8b8asd8327bh/125.pdf 
... 

luego escribir usted mismo un pequeño script PHP que enviar cabeceras apropiadas, y pasar el contenido del archivo a través.

por ejemplo:

<?PHP 
//pdf.php 
$id = $_GET['id']; 

//make sure nobody is doing anything sneaky. is_numeric() might do the trick if the IDs are always integers. 
if (!some_validation_passes($id)){ 
    die(); 
} 
<?php 

header('Content-type: application/pdf'); 
header('Content-Disposition: attachment; filename="'.$id.'.pdf"'); 
readfile('asd8b8asd8327bh'.$id.'pdf'); 

Ahora, lo anterior es realmente no es mejor que simplemente servir a los archivos directamente (aún), ya que la gente todavía puede incrementar el parámetro id en la cadena de consulta.

Pero debe ser capaz de averiguar cómo manejar la autorización con bastante facilidad.

+0

Esto es seguridad a través de la oscuridad. En otras palabras, no seguro. – Borealid

+0

@Borealid Usted dice eso como si no calificara explícitamente mi respuesta en la primera línea. No entrar en un debate sobre la seguridad a través de la oscuridad, sino "Esto es software. En otras palabras, no es seguro". O "Este es un sistema de contraseñas, y por lo tanto inseguro". De hecho, ahora que lo pienso, mi solución es tan segura como una contraseña segura, suponiendo que ningún agujero no relacionado permita que un atacante incluya directorios. – timdev

0

Hacer una carpeta web inaccesible a través de chmod. PHP aún podrá incluir/requerir lo que sea que esté en el servidor, pero los usuarios no podrán navegar a los archivos nunca.

Ejemplo: Esto se establece en 770, el usuario y el grupo de IE pueden leer/escribir/ejecutar, el otro no puede hacer nada.

+0

Esta respuesta es incorrecta. Salvo una configuración SuExec/CGI, PHP usa los permisos del servidor web. Si el archivo no es accesible para el servidor web, tampoco es accesible para PHP. – Borealid

+0

Tengo una carpeta establecida en 770 y puedo incluirla, pero no puedo navegar directamente en mi navegador. – Robert

+0

También creo que ha entendido mal, el servidor web todavía tiene permisos, el usuario y el grupo tienen permisos en 770, otros no. Así que esto le da a PHP acceso completo a los archivos, el navegador web no obtendrá nada. – Robert

1

Dado que PHP utiliza los permisos del usuario del servidor web, no hay manera de restringir el acceso a los archivos sin que ninguno:

  • La colocación de ellos fuera de la docroot
  • Cambio de la configuración del servidor web para no permitir el acceso a las
  • archivos
  • Cambio del archivo por lo que será interpretado por el servidor web, ocultando así su contenido

poniéndolos en una base de datos cuenta como outsi de el DOCROOT. Para la tercera opción, podría hacer que los PDF sean archivos PHP, pero sinceramente, eso sería complicado.

Te recomiendo que te comuniques con GoDaddy y veas si tienen alguna forma de configurar los permisos de archivos por directorio.

+0

Inteligente. Suponiendo que OP no puede hacer nada con el servidor, me gusta su tercera opción, junto con el código básico que describí. – timdev

Cuestiones relacionadas