2010-12-26 14 views
38

Tengo un sitio web que muestra galerías. Los usuarios pueden cargar su propio contenido desde la web (ingresando una URL) o cargando una imagen desde su computadora.donde es el mejor lugar para guardar imágenes de usuarios subir

Estoy almacenando la URL en la base de datos que funciona bien para el primer caso de uso, pero necesito averiguar dónde almacenar las imágenes reales si un usuario carga desde su computadora.

¿Hay alguna recomendación aquí o las mejores prácticas sobre dónde debo guardarlas?

¿Debo guardarlos en la aplicación de datos o en las carpetas de contenido? ¿No deberían almacenarse en absoluto en el sitio web porque es contenido del usuario?

Respuesta

56

NO debe almacenar las cargas del usuario en ningún lugar al que se pueda acceder directamente mediante una URL conocida dentro de la estructura de su sitio. Este es un riesgo de seguridad ya que los usuarios pueden cargar archivos .htm y .js. Incluso un archivo con la extensión correcta puede contener código malicioso que puede ser ejecutado en el contexto de su sitio por un usuario autenticado que permita ataques en el lado del servidor o del lado del cliente.

Consulte por ejemplo http://www.acunetix.com/websitesecurity/upload-forms-threat.htm y What security issues appear when users can upload their own files? que mencionan algunos de los problemas que debe tener en cuenta antes de permitir que los usuarios carguen archivos y luego presentarlos para su descarga dentro de su sitio.

  1. No ponga los archivos dentro de su estructura de directorio del sitio web normal

  2. No utilice el nombre del archivo original que el usuario le dio. Puede agregar un encabezado de disposición de contenido con el nombre del archivo original para que puedan volver a descargarlo como el mismo nombre de archivo, pero la ruta y el nombre del archivo en el servidor no deberían ser algo en lo que el usuario pueda influir.

  3. No confíe en los archivos de imagen - cambiar el tamaño de ellos y ofrecer sólo la versión redimensionada para su descarga posterior

  4. No confíe en los tipos MIME o extensiones de archivo, abra el archivo y manipularlo para asegurarse de que es lo que se afirma ser.

  5. Limite el tamaño y el tiempo de carga.

+2

Me encantaría un poco más de detalle en los n. ° 3 y n. ° 4. ¿El cambio de tamaño asegura que en realidad son imágenes? Y con 'abrirlo', ¿quieres ver los primeros bytes que se supone que te dicen el tipo de archivo? – Omar

+3

3. esencialmente elimina la posibilidad de que los metadatos corruptos se hayan incluido en el archivo de imagen para atacar un navegador mal escrito u otro software de imagen. 4. Sí, compruebe que realmente se trata de un archivo de imagen con los metadatos de imágenes correspondientes al tipo que dice ser. ¿Puedes cargarlo en un mapa de bits, etc.? Los usuarios a menudo subirán imágenes corruptas a su sitio, rechazarlas temprano es una buena idea. –

+2

mencionas "no coloques los archivos dentro de la estructura de directorio de tu sitio web normal. Pero si no hago eso, ¿cómo puedo vincularlo a este contenido? – leora

4

Una forma es almacenar la imagen en una tabla de base de datos con un campo varbinary.

Otra forma sería almacenar la imagen en la carpeta App_Data y crear una subcarpeta para cada usuario (~/App_Data/[userid] /myImage.png).

Para ambos enfoques, necesitaría crear un método de acción separado que permita acceder a las imágenes.

+0

Tenemos el método de base de datos para contenido común estático en sitios web. Lo usamos para llamar versiones. Esto funciona bien, y podemos comprimir el blob binario. – Arnej65

3

Al cargar imágenes, debe verificar el contenido del archivo antes de cargarlo. El método de extensión de archivo no es confiable.

Utilice el método del número mágico para verificar el contenido del archivo, que será una manera fácil.

Véase el stackoverflow post y ver la list of magic numbers

Una forma de ahorrar el archivo es la conversión a formato binario y guardar en la base de datos y el próximo método es el uso de la carpeta App_Data.

La opción de almacenamiento se basa en sus requisitos. Ver también this post

Conjunto límite de subida estableciendo la propiedad maxRequestLength a Web.Config como este, donde se especifica el tamaño del archivo en KB

<httpRuntime maxRequestLength="51200" executionTimeout="3600" /> 
8

En función de los recursos que tiene a implementar algo como esto, es extremadamente beneficioso para almacenar todo esto en Amazon S3.

Una vez que obtenga la carga, simplemente empújela hacia Amazon y estacione la URL en su base de datos como lo hace con las otras imágenes. Como se mencionó anteriormente, probablemente sería conveniente abrir la imagen y cambiar su tamaño antes de enviarla. Esto comprueba que en realidad es una imagen y se asegura de que no se presente accidentalmente una imagen de resolución completa de la cámara a un usuario final.

Hacer esto ahora lo hará mucho, mucho más fácil si alguna vez tiene que migrar/conmutar por error su sitio y no desea sincronizar gigabytes de activos de imagen.

+0

Me gusta esta respuesta, pero también debe considerar la seguridad. El uso de S3 minimizará la cantidad de tráfico que pasa por su sitio. Pero si quieres asegurarte de que el archivo es lo que dicen que es, aplicaría un filtro a la imagen antes de subirlo a s3, de esa forma sabrás que una imagen es que el filtro tiene éxito. – Angelom

+0

De hecho. Eso era algo así como lo que obtenía con el paso de cambio de tamaño, pero de cualquier forma, es una buena idea tener algún tipo de buen control sólido para tener una imagen real. – dmnc

-2

Puede guardar sus datos de confianza en paralelo a la carpeta htdocs/www para que ningún usuario pueda acceder a esa carpeta. También puede agregar la autenticación .htaccess en sus datos de confianza (para .htaccess debe mantener su archivo .htpasswd en paralelo de la carpeta htdocs/www) si está usando apache.

Cuestiones relacionadas