Foros del Web » Programando para Internet » PHP »

Up/Download de archivos con SEGURIDAD

Estas en el tema de Up/Download de archivos con SEGURIDAD en el foro de PHP en Foros del Web. Hola a todos, estos días he estado haciendo un scrip que sube y baja archivos, está basado en muchos otros que he ido viendo por ...
  #1 (permalink)  
Antiguo 29/12/2004, 05:35
 
Fecha de Ingreso: noviembre-2004
Mensajes: 17
Antigüedad: 13 años, 1 mes
Puntos: 0
Up/Download de archivos con SEGURIDAD

Hola a todos,

estos días he estado haciendo un scrip que sube y baja archivos, está basado en muchos otros que he ido viendo por ahí.

Lo que me gustaría hacer ahora es proteger los archivos subidos, es decir, restringirlos. Navegando por mi web no se puede llegar a la zona de descargas si no se está registrado, pero en el momento que un usuario conociera el directorio donde guardo los archivos que pretendo restringir, puede acceder a ellos fácilmente a través de la URL del navegador, sin identificarse.

Mi servidor es linux, y puedo modificar los permisos del directorio donde guardo los archivos subidos, por ejemplo deshabilitar los permisos de lectura y escritura sobre el dirctorio en cuestión para el grupo de usuarios "other". Así, no se puede acceder a ellos, pero el problema es que el php se ejecutaría sin esos permisos, y los usuarios registrados tampoco podrían hacer nada. No sé si hay algo que hacer a través del bit uid, activarlo, o meterme ahí sería un agujero de seguridad más grave aún...

¿Cómo puedo hacerlo? Ayuda!

Gracias!
  #2 (permalink)  
Antiguo 29/12/2004, 07:44
Ex Colaborador
 
Fecha de Ingreso: junio-2002
Mensajes: 9.091
Antigüedad: 15 años, 6 meses
Puntos: 16
Hola,

No hagas un link al fichero, sino a un script PHP que devuelva el contenido del fichero, via un readfile() (www.php.net/readfile). En el script validas que el usuario esta identificado. Los ficheros de verdad los ocultas fuera del directorio raiz del sitio, o en una carpeta configurada en el servidor web de forma que su contenido no sea accesible via HTTP, solo via sistema operativo.

Saludos.

PD: Busca en el foro, se ha comentado muchas veces.
__________________
Josemi

Aprendiz de mucho, maestro de poco.
  #3 (permalink)  
Antiguo 29/12/2004, 09:35
 
Fecha de Ingreso: noviembre-2004
Mensajes: 17
Antigüedad: 13 años, 1 mes
Puntos: 0
Gracias, Josemi.

He estado mirando lo que me has comentado y hay muchas cosas hechas por ahí con esa idea. Lo que pasa es que todo eso se basa en que el archivo "restringido" está en un directorio fuera del document_root, y eso es lo que no me gusta... Resulta que mi script está pensado para que el usuario suba su archivo, y otro pueda bajarlo (ambos registrados). Para que al subirlos estén en el directorio restringido (que está fuera del document_root), debe ser posible escribir ese directorio. Para eso, ¿puedo subir los archivos a un directorio cualquiera dentro del document_root (como hago ahora) y luego moverlos con move_uploaded_file() a un directorio de fuera del document_root?

Mi idea era tener 2 subdirectorios al mismo nivel, uno publico y otro restringido, y que al restringido se pudiera acceder de alguna forma si se ha habierto una sesión y se está correctamente autentificado. Además he hecho el código para mostrar los archivos subidos a ambas carpetas... ¿Te sirve si escribo aqui el codigo?

¿Es posible hacer lo que quiero sin recurrir a la carpeta fuera del document_root?

Gracias
  #4 (permalink)  
Antiguo 29/12/2004, 10:09
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 15 años, 11 meses
Puntos: 126
Cita:
debe ser posible escribir ese directorio. Para eso, ¿puedo subir los archivos a un directorio cualquiera dentro del document_root (como hago ahora) y luego moverlos con move_uploaded_file() a un directorio de fuera del document_root?
Cuando haces tu move_uploaded_file() puedes mover directamente el archivo que queda en el "temporal" donde PHP los deja al subirlo por HTTP hacia cualquier directorio de tu servidor que tenga permisos de escritura y que PHP no esté limitado para su acceso (con restricciones tipo open_base_dir y cosas así ..).

Cita:
Mi idea era tener 2 subdirectorios al mismo nivel, uno publico y otro restringido, y que al restringido se pudiera acceder de alguna forma si se ha habierto una sesión y se está correctamente autentificado.
Bueno .. independientemente que tengas un script en PHP que lea el archivo y lo entrege al cliente (vía header() y readfile() y afines) .. los permisos que des a tus usuarios los defines en tu programación en el archivo (script) que destines para la descarga de archivos.


Cita:
¿Es posible hacer lo que quiero sin recurrir a la carpeta fuera del document_root?
Parace que con un .htaccess y comandos tipo "allow from ..." de Apache (supongo que usas Apache como servidor HTTP) podrías limitar los accesos de tus archivos a sólo "localhost" como HOST .. algo tipo (no estoy seguro si será del todo correcto .. verificalo en un manual de Apache o bien en el foro de "Servidores web -> Apache"):

<Limit GET POST PUT>
order deny,allow
deny from all
allow from 127.0.0.1
</Limit>

Es decir .. sólo autorizas a la "IP" 127.0.0.1 (= a Localhost) para acceder a ese directorio ..por ende sólo un script tuyo PHP que corra en ese servidor podría leer/abrir tu archivo .. no desde una llamada por HTTP ..

Un saludo,

Última edición por Cluster; 29/12/2004 a las 10:12
  #5 (permalink)  
Antiguo 30/12/2004, 03:36
 
Fecha de Ingreso: noviembre-2004
Mensajes: 17
Antigüedad: 13 años, 1 mes
Puntos: 0
Muchas gracias Cluster, estoy probando las cosas que me has dicho y he leído ya bastante desde ayer.

Sólo una duda:

si tengo un enlace desde una página de www.midominio.com (tipo <a href... ></a>) a un archivo de la carpeta (también de www.midominio.com) cuyo acceso quiero restringir, ¿qué IP sería la que se comprueba en el .access, la del usuario que pincha el enlace, la de localhost o la de www.midominio.com? Si en lugar de ser un enlace html fuera a través de PHP, sería localhost, pero al ser html (aunque esté dentro de una página llamada index.php entre etiquetas html) ya no estoy seguro.

Lo pregunto porque no lo puedo comprobar, ya que la web que estoy haciendo de momento sólo es visible en una intranet que tenemmos, aún no es accesible desde fuera.

Saludos.
  #6 (permalink)  
Antiguo 30/12/2004, 06:17
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 15 años, 11 meses
Puntos: 126
Cuando lo haces por HTTP .. la IP se refiere a la del cliente ... cuando lo hace PHP (el acceso) el "cliente" es PHP y ese en tu caso sería "localhost".

Puedes hacer tus pruebas en tu intranet .. accede dese un PC de tu intranet a tu servidor y lo compruebas. Es la misma filosofía que si lo haces desde Internet en general.

Un saludo,
  #7 (permalink)  
Antiguo 30/12/2004, 09:54
 
Fecha de Ingreso: noviembre-2004
Mensajes: 17
Antigüedad: 13 años, 1 mes
Puntos: 0
Muchas gracias, cluster. Te las sabes todas! Ahora CASI lo tengo todo, pero hay un último detalle que me vendría muy bien: ¿sabes cómo se puede prohibir el método GET sólo si se hace desde fuera de localhost?

En .htaccess hago lo que has comentado, pero no sé por qué se interpreta que el cliente php no es localhost y me deniega el archivo restringido. Si quito el archivo .htaccess se baja bien, y en él tengo exactamente lo que pones en el msj #4 de este hilo.

He pensado que si se ignoran todos los get, salvo el que pone mi archivo index.php al llamar a download.php?file=dibujo.zip, nunca podrá nadie usar la URL para descargarse nada escribiendo lo mismo que escribe mi script php, porque sólo "se le echaría cuenta" al GET si prodece del index.php, no si se ha escrito como URL.

En php.ini puedo quitar la letra "G" de la directiva "variables_order", así nunca se podría hacer GET, pero entonces ni siquiera podría hacerlo mi index.php. Lo que estaría bien sería algo del tipo:

if(127.0.0.1)
variables_order = "EGPCS"
else
variables_order = "EPCS"

en el php.ini.

¿Puedo hacer algo? ¿Por qué no me funciona el .htacces (siempre me deniega el acceso incluso siendo localhost)?

Saludos y gracias!
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 20:02.