PHP | Seguridad para permitir subidas de usuarios.

7

Mi situación:

Estoy creando una aplicación web con PHP que permite a los usuarios escanear sus archivos en busca de virus. Permite al usuario cargar sus archivos a través del tipo de entrada html "archivo" o mediante una URL. He construido con éxito el lado html y PHP de las cosas y los usuarios pueden cargar archivos con éxito en mi servidor. Estoy usando Windows Server 2012 R2 con IIS como mi servidor.

Mi pregunta:

Por lo que yo sé, hay poca o ninguna seguridad (tanto en el lado del script como en el del servidor) para evitar vulnerabilidades de seguridad / ataques en mi sitio web o, lo que es peor, en el propio servidor. Soy consciente de que los atacantes podrían cargar y ejecutar archivos que pueden piratear mi servidor. Por lo tanto, ¿qué pasos puedo tomar para intentar eliminar estos problemas? .

Cosas de las que soy consciente:

Debido a la investigación que realicé, es a mi entender que potencialmente podría hacer lo siguiente para fortalecerme, sin embargo, estas son todas teorías, y no tengo idea de cómo implementarlas realmente (de ahí la razón por la que soy preguntando):

  • Restricción en los tipos de archivos (Sí, potencialmente podría bloquear los archivos .php, pero como ejemplo, no puedo bloquear los .exe comunes ya que el usuario probablemente escanearía un archivo ejecutable) ¿Cuál es el saldo correcto para este tipo de servicio, ya que la limitación de demasiados tipos de archivos simplemente elimina la facilidad de uso

  • Almacenamiento de archivos cargados en una unidad diferente: el directorio de mi sitio está en la unidad C y tengo una unidad D vacía que podría usar. ¿Cómo deshabilito el servidor para que no ejecute nada en la unidad específica? ¿Cómo evito que los hackers naveguen hacia esa unidad y ejecuten los archivos cargados?

Cosas que he probado:

  • He creado una función para cambiar el nombre del archivo cargado en un hash md5, con una ID única al principio, por lo que el usuario no puede identificar el archivo fácilmente.
  • Tipo de archivo limitado para eliminar las cargas .php? Tal vez hay otros que serían válidos para mi propósito?

Conclusion:

Esencialmente, así como respuestas a las preguntas menores arriba. Estoy buscando una lista de acciones que puedo tomar para fortalecer la aplicación y el servidor, para eliminar cualquier posible amenaza. Gracias

Código:

Como nota al margen, a continuación puedes ver mi código. Sólo en caso de que veas algo serio allí. O hay seguridad adicional que se puede agregar al código:

PHP:

$upload_directory = "uploads/";
    $uploaded_file = $upload_directory . basename($_FILES["file"]["name"]);
    $upload_ok = 1;

    $image_file_type = pathinfo($uploaded_file, PATHINFO_EXTENSION);

    // check for files bigger then 8mb
    if($_FILES["file"]["size"] > 8388608){
        print "your file exceeds 8mb";
        $upload_ok = 0;
        exit();
    }

    // only allow certain file types
    if($image_file_type != "jpg" && $image_file_type != "png" && $image_file_type != "jpeg" && $image_file_type != "gif"){
        print "invalid file type";
        $upload_ok = 0;
        exit();
    }

    // upload it
    if($upload_ok != 0){
        move_uploaded_file($_FILES["file"]["tmp_name"], $uploaded_file);
    }

HTML:

<form method="post" action="index.php" enctype="multipart/form-data">

    <label>Select Desired File</label><br>
    <input type="file" name="file" id="file">

    <input type="submit" name="submit" value="Scan File"> 
</form> 
    
pregunta Jimmy 20.02.2015 - 17:42
fuente

3 respuestas

4

Cuando se trata de permitir la carga de archivos de usuarios, debes tener mucho cuidado. Esto es solo una lista de cosas con las que empezar, desde la parte superior de mi cabeza:

Asegúrese de que los usuarios no puedan ejecutar los archivos

  • Configure su PHP de tal manera que no considere usar la extensión de archivo PHP en las carpetas donde existen los archivos PHP.
  • Asegúrese de que los permisos para los archivos estén configurados correctamente. Si no es necesario que los archivos uploaded tengan permisos de ejecución, ¿por qué deberían hacerlo?

Evitar que los usuarios capturen archivos arbitrarios

A menos que usted también los quiera, el usuario no debería poder enumerar todos los archivos cargados en su servicio. De hecho, según su descripción del servicio, no hay razón para que puedan volver a descargar el archivo.

  • Proporcione identificadores únicos difíciles de adivinar en el nombre del archivo. Muchos sitios utilizan nombres de archivos largos y complejos para cosas tan triviales como las imágenes para proporcionar metadatos y evitar la enumeración.
  • Asegúrese de que su sistema esté configurado para detectar la enumeración. Un usuario no debería poder hacer miles de conjeturas incorrectas en el nombre del recurso. Puede hacer esto a través de tablas i.p, fail2ban, IDS, aplicación, base de datos. Depende de muchas cosas y de muchas maneras de ir.
  • Si los usuarios no necesitan recuperar dicho archivo de su servidor, asegúrese de llevarlo a un lugar donde no se pueda acceder directamente (como fuera de webroot).
  • Considere alojar sus archivos en un servidor diferente al de otras partes de la aplicación (como la lógica de negocios y demás).

Asegurarse de que los archivos no causen problemas directamente en su sistema

Usted describe su servicio como un servicio de detección de virus. Lo que estás tratando de hacer puede ser peligroso. No es inconcebible que un virus pueda aprovechar el AV para escalar privilegios.

  • Realice un análisis básico para determinar la validez del archivo antes de enviarlo a AV. Los usuarios no deben poder enviar archivos gravemente dañados que pueden bloquear el AV.
  • Comprueba los encabezados.
  • Usa programas como fileinfo.
  • Compare con la información del tipo de archivo conocido.
  • escanee el archivo en busca de intentos obvios de mutilación / difamación. Por ejemplo, un archivo con 10 mil caracteres A podría estar probando su sistema.

Asegurarse de que el AV no causará problemas

  • asegúrese de estar usando un software de AV confiable que esté completamente actualizado y actualizado.
  • Asegúrese de que el software AV tenga los derechos adecuados y no exponga puertos innecesarios.

Aislar el sistema en caso de incumplimiento

  • Nuevamente, asegúrese de que el sistema que posee los archivos tenga derechos mínimos.
  • Intente usar un contenedor / jail / sandbox de algún tipo para limitar la efectividad de un intento de explotación.
respondido por el baordog 20.02.2015 - 19:27
fuente
3

Cuando se cargue el archivo, sugeriría usar finfo para determinar qué tipo de archivo es, independientemente de la extensión del archivo y realice acciones específicas según el resultado.

Si decide que la carpeta de carga debería estar en algún lugar del documento raíz, le recomiendo que ejecución inhabilitada de archivos PHP para esa carpeta específica.

Preferiría usar un algoritmo de hashing más fuerte para cambiar el nombre de tus archivos combinados con una cadena aleatoria por archivo. La forma en que describe la forma en que desea cambiar el nombre de sus archivos parece bastante predecible y yo, como atacante, intentaría este tipo de cosas para adivinar el nombre del archivo.

    
respondido por el Jeroen - IT Nerdbox 20.02.2015 - 18:30
fuente
-3

Una técnica menor que utilicé es la siguiente. Tenía un trozo de código C que escribí que mira los primeros 4-8 bytes de cualquier archivo e identifica el tipo. Como C estaba cerca de PHP, porté esa rutina a PHP. En algún otro código PHP comparé ese tipo con la extensión. Si hay un desajuste, por ejemplo. una extensión JPG es en realidad un archivo de Microsoft EXE, lo rechacé. Esto es importante porque una clase de vulnerabilidades de Windows simples que involucran hacer que un archivo EXE parezca un archivo de imagen o algo más, es probable que el usuario haga doble clic.

    
respondido por el Icann 20.02.2015 - 19:13
fuente

Lea otras preguntas en las etiquetas