[php-arg] Acceso limitado a recursos estaticos

10 views
Skip to first unread message

Federico

unread,
May 10, 2010, 5:48:27 PM5/10/10
to php...@googlegroups.com
Hola,

Queria comentarles un problema que tengo para ver si alguien me puede
ayudar en la solucion.

El tema es asi: necesito limitar el acceso a los recursos estaticos
(imagenes, pdfs, txts, etc) subidos por los usuarios a la aplicación.
Por el momento estoy apuntando las URLs de los recursos a un php donde
se valida la session del usuario, se checkea que el recurso exista y
que el usuario tenga permiso para verlo y si todo sale bien seteo los
headers con el mime y devuelvo el contenido del archivo.

Hasta ahi todo bien. Funciona.

El problema esta en que el script tiene una carga importante y eso
hace que traer 10 imagenes simultaneamente sea bastante pesado y
lento. Tambien, por alguna razon Firefox no cachea estos recursos, por
mas que devuelva el mime en el header.

Creo que lo ideal seria que el navegador cachee los recursos. Pero, en
ese caso, que pasa si cambia un permiso y un usuario ya no tiene
permitido seguir viendo ese recurso?

Se les ocurre alguna otra alternativa? Como "protegen" ustedes los
recursos subidos por los usuarios en una aplicacion?


Saludos y gracias,
Federico.

--
Has recibido este mensaje porque estás suscrito al grupo "Grupo PHP Argentina" de Grupos de Google.
Para publicar una entrada en este grupo, envía un correo electrónico a php...@googlegroups.com.
Para anular tu suscripción a este grupo, envía un correo electrónico a php-arg+u...@googlegroups.com
Para tener acceso a más opciones, visita el grupo en http://groups.google.com/group/php-arg?hl=es.

Tordek

unread,
May 10, 2010, 7:04:51 PM5/10/10
to php...@googlegroups.com
On 10/05/10 18:48, Federico wrote:
> Hola,
> El problema esta en que el script tiene una carga importante y eso
> hace que traer 10 imagenes simultaneamente sea bastante pesado y
> lento. Tambien, por alguna razon Firefox no cachea estos recursos, por
> mas que devuelva el mime en el header.

Bienvenido al problema de la autenticación en REST.

El navegador no puede cachear recursos POST (por razones obvias), y
algunos no cachean cuando tienen un "query string"... creo que con
las cookies se puede, pero ni idea.

La otra es que tengas mal configurada la forma en que cacheas...
expires, etags, no sé.

Decís que el script es pesado... ¿qué tan pesado es? ¿qué tan
estrictos son tus requisitos?, y ¿no podés simplificarlo?

Recordemos que, de última, cualquier semblanza de seguridad si no se
usa https es mentira.

> Se les ocurre alguna otra alternativa? Como "protegen" ustedes los
> recursos subidos por los usuarios en una aplicacion?

Seguridad por obscuridad. Dale una url única a cada usuario (basada
en un crypt de su user, o algo). Si, además, encriptás el nombre del
objeto, es un poco más difícil adivinar otras cosas del usuario.

No es la gran solución, pero no sé si haya mucha más seguridad en lo
tuyo, dado que, al fin y al cabo, man in the middle sirve para los dos.

>
> Saludos y gracias,
> Federico.
>


--
Guillermo O. «Tordek» Freschi. Programador, Escritor, Genio Maligno.
http://tordek.com.ar :: http://twitter.com/tordek
http://www.arcanopedia.com.ar - Juegos de Rol en Argentina

Adrian Ramiro

unread,
May 10, 2010, 7:44:40 PM5/10/10
to php...@googlegroups.com
Federico, se me ocurre que tu problema de consumo de recursos se puede deber a autenticar el usuario, el acceso al recurso y la existencia del mismo para cada hit, tal vez puedas almacenar esos datos en la session y así acceder muchas menos veces a la DDBB.
Por lo demás coincido con Tordek sumándole un poroto más a lo de URIs únicas por usuario/recurso, incluso podrías generar la URI por session también y complicarla un poco más, pero como dijo Tordek, esto es solo obfuscar un poco el acceso, no es LA solución de seguridad

Saludos.


 Adrián




On 10/05/2010 20:04, Tordek wrote:
On 10/05/10 18:48, Federico wrote:
Hola,
El problema esta en que el script tiene una carga importante y eso
hace que traer 10 imagenes simultaneamente sea bastante pesado y
lento. Tambien, por alguna razon Firefox no cachea estos recursos, por
mas que devuelva el mime en el header.

Bienvenido al problema de la autenticación en REST.

El navegador no puede cachear recursos POST (por razones obvias), y algunos no cachean cuando tienen un "query string"... creo que con las cookies se puede, pero ni idea.

La otra es que tengas mal configurada la forma en que cacheas... expires, etags, no sé.

Decís que el script es pesado... ¿qué tan pesado es? ¿qué tan estrictos son tus requisitos?, y ¿no podés simplificarlo?

Recordemos que, de última, cualquier semblanza de seguridad si no se usa https es mentira.

Se les ocurre alguna otra alternativa? Como "protegen" ustedes los
recursos subidos por los usuarios en una aplicacion?

Seguridad por obscuridad. Dale una url única a cada usuario (basada en un crypt de su user, o algo). Si, además, encriptás el nombre del objeto, es un poco más difícil adivinar otras cosas del usuario.

No es la gran solución, pero no sé si haya mucha más seguridad en lo tuyo, dado que, al fin y al cabo, man in the middle sirve para los dos.


Saludos y gracias,
Federico.



--

Silvio

unread,
May 11, 2010, 8:51:10 AM5/11/10
to Grupo PHP Argentina


On May 10, 6:48 pm, Federico <federi...@gmail.com> wrote:
> Hola,
>
> Queria comentarles un problema que tengo para ver si alguien me puede
> ayudar en la solucion.
>
> El tema es asi: necesito limitar el acceso a los recursos estaticos
> (imagenes, pdfs, txts, etc) subidos por los usuarios a la aplicación.
> Por el momento estoy apuntando las URLs de los recursos a un php donde
> se valida la session del usuario, se checkea que el recurso exista y
> que el usuario tenga permiso para verlo y si todo sale bien seteo los
> headers con el mime y devuelvo el contenido del archivo.
>
> Hasta ahi todo bien. Funciona.
>
> El problema esta en que el script tiene una carga importante y eso
> hace que traer 10 imagenes simultaneamente sea bastante pesado y
> lento. Tambien, por alguna razon Firefox no cachea estos recursos, por
> mas que devuelva el mime en el header.
>
> Creo que lo ideal seria que el navegador cachee los recursos. Pero, en
> ese caso, que pasa si cambia un permiso y un usuario ya no tiene
> permitido seguir viendo ese recurso?
>
> Se les ocurre alguna otra alternativa? Como "protegen" ustedes los
> recursos subidos por los usuarios en una aplicacion?
>
> Saludos y gracias,
> Federico.


La única forma es como hacés vos ... cada vez que se ejecuta el script
se validan credenciales.
No creo que eso resulte costoso. De última, revisá ese script de
validación y optimizalo.

Podrás cachear los recursos modificando los headers. En el caso de que
el cambio de permisos suponga un problema grave, la forma de impedir
el acceso es modificar la URL del objeto. Esto no es algo definitivo
ya que si alguien tuvo acceso en algún momento, pudo haber descargado
el archivo en su PC y listo.

Por otro lado si es mucho 10 imágenes para el servidor, paginá y
listo.

Silvio.

Mariano Iglesias

unread,
May 11, 2010, 8:56:53 AM5/11/10
to php...@googlegroups.com
Usa eTags, haciendo que expire cuando el usuario no tiene mas acceso, y dejando la expiracion al modified date del archivo cuando tiene acceso:

http://us.php.net/manual/en/function.header.php#85146

Fijate que como vas a estar usando sesion tambien vas a tener que poner el cache control como private:

http://blueprint.intereactive.net/caching-etags-php-sessions/



On 05/11/2010 09:51 AM, Silvio wrote:
La única forma es como hacés vos ... cada vez que se ejecuta el script
se validan credenciales.
No creo que eso resulte costoso. De última, revisá ese script de
validación y optimizalo.

Podrás cachear los recursos modificando los headers. En el caso de que
el cambio de permisos suponga un problema grave, la forma de impedir
el acceso es modificar la URL del objeto. Esto no es algo definitivo
ya que si alguien tuvo acceso en algún momento, pudo haber descargado
el archivo en su PC y listo.

Por otro lado si es mucho 10 imágenes para el servidor, paginá y
listo

--
-MI
Coding Ninja @ CRICAVA Technologies
 
Blog: marianoiglesias.com.ar
Twitter: @mgiglesias

Mariano Iglesias

unread,
May 11, 2010, 8:59:48 AM5/11/10
to php...@googlegroups.com
Me acabo de acordar que cuando yo use etags use funciones nativas (del pecl_http):

http://ar2.php.net/manual/en/function.http-cache-etag.php

Con eso cacheas. Despues usas http_send_file (http://ar2.php.net/manual/en/function.http-send-file.php) para mandar la imagen.

Luego para matchear el etag:

http://ar2.php.net/manual/en/function.http-match-etag.php


On 05/11/2010 09:56 AM, Mariano Iglesias wrote:
Usa eTags, haciendo que expire cuando el usuario no tiene mas acceso, y dejando la expiracion al modified date del archivo cuando tiene acceso:

http://us.php.net/manual/en/function.header.php#85146

Fijate que como vas a estar usando sesion tambien vas a tener que poner el cache control como private:

http://blueprint.intereactive.net/caching-etags-php-sessions/

--
-MI
Coding Ninja @ CRICAVA Technologies
 
Blog: marianoiglesias.com.ar
Twitter: @mgiglesias

Mariano Iglesias

unread,
May 11, 2010, 9:06:34 AM5/11/10
to php...@googlegroups.com
Aca te dejo un pedazo de codigo de una custom CakePHP view que hice, para que veas mas o menos la onda:

http://pastium.org/view/4a9329d192f20568c471a437c632a7cb


On 05/11/2010 09:59 AM, Mariano Iglesias wrote:
Me acabo de acordar que cuando yo use etags use funciones nativas (del pecl_http):

http://ar2.php.net/manual/en/function.http-cache-etag.php

Con eso cacheas. Despues usas http_send_file (http://ar2.php.net/manual/en/function.http-send-file.php) para mandar la imagen.

Luego para matchear el etag:

http://ar2.php.net/manual/en/function.http-match-etag.php

--
-MI
Coding Ninja @ CRICAVA Technologies
 
Blog: marianoiglesias.com.ar
Twitter: @mgiglesias

Mariano Gomez

unread,
May 11, 2010, 1:22:55 PM5/11/10
to php...@googlegroups.com
Recomiendo que leas sobre semaforos, generalmente estan hechos en java/c++, pero para el caso particular tuyo servirian, haciendo una clase con una vble static y dos metodos que modifiquen dicha vble, uno para que permita el acceso al recurso si dicha vble static no tiene el valor tope que vos le asignes, y otro que decremente dicha vble cuando se termina de ejecutar el servicio. De esa forma te aseguras que a lo sumo ese servicio se esta brindando para N usuarios

Federico

unread,
May 11, 2010, 4:07:42 PM5/11/10
to php...@googlegroups.com
Tordek,

Gracias por la respuesta.

Paso a aclarar algunos puntos:
- Estoy haciendo requests GET sin usar "query string". Uso
mod_rewrite. El formato es asi:
view/<path_a_los_recursos_del_user>/nombre_imagen.jpg
- Estoy usando kohana, osea que cada request de un recurso se
inicializa todo el framework.
- Estoy usando ssl.

Por ahora lo que mas me preocupa es la performance y en cuanto a
seguridad, que no se pueda acceder a los recursos desde afuera.

Hacer un hash loco es una buena opción en cuanto a seguridad, pero
sigue estando el problema de la performance.

Y si, la única diferencia entre los request de los recursos comunes y
los de los usuarios es el etag. Ahora no recuerdo bien, pero en su
momento intente setearlo y no pude. Tendría que fijarme mas
detenidamente.


2010/5/10 Tordek <ked...@gmail.com>:

Federico

unread,
May 11, 2010, 4:16:03 PM5/11/10
to php...@googlegroups.com
Adrián,

Estoy usando Kohana. El mayor hit en la performance es cargar todo en
framework en cada request. Estoy usando memcache para cachear objetos
asique, la mayoria de las veces no necesito consultar la DB.
Con respecto a la seguridad, si, las uris unicas estan buenas. Creo
que voy a tener que implementar algo de eso.

2010/5/10 Adrian Ramiro <adri...@gmail.com>:

Guido

unread,
May 13, 2010, 9:29:49 PM5/13/10
to Grupo PHP Argentina
a ver si entendi bien...creo que esto te puede servir a vos y a
alguien mas que preguntó alguien similar hace unos dias...

fijate si lo podes solucionar usando el mod_setenvif de apache
http://httpd.apache.org/docs/2.2/mod/mod_setenvif.html

basicamente lo que haces con esto es permitir que se accedan a los
archivos dentro de un directorio solo si vienen referidos de un link
de tu sitio. De esta forma, si la pagina donde "linkeas" al archivo
que no queres que acceda cualquiera necesita que el usuario tenga
sesion iniciada, logras lo que queres.

Tordek

unread,
May 14, 2010, 2:49:07 PM5/14/10
to php...@googlegroups.com
On 13/05/10 22:29, Guido wrote:
> a ver si entendi bien...creo que esto te puede servir a vos y a
> alguien mas que preguntó alguien similar hace unos dias...
>
> fijate si lo podes solucionar usando el mod_setenvif de apache
> http://httpd.apache.org/docs/2.2/mod/mod_setenvif.html
>
> basicamente lo que haces con esto es permitir que se accedan a los
> archivos dentro de un directorio solo si vienen referidos de un link
> de tu sitio. De esta forma, si la pagina donde "linkeas" al archivo
> que no queres que acceda cualquiera necesita que el usuario tenga
> sesion iniciada, logras lo que queres.
>
Sí, pero sigue siendo seguridad por obscuridad, y en este caso es
mucho peor:

Si el sitio tiene URLs "lindas", mis imágenes las podré acceder
desde http://ejemplo.com/tordek/imagenes, por ejemplo; falsificar el
encabezado es trivial.

--
Guillermo O. «Tordek» Freschi. Programador, Escritor, Genio Maligno.
http://tordek.com.ar :: http://twitter.com/tordek
http://www.arcanopedia.com.ar - Juegos de Rol en Argentina

Reply all
Reply to author
Forward
0 new messages