Pregunta

La compañía para la que trabajo recientemente se ha visto afectada con muchos ataques de inyección de encabezado y carga de archivos en los sitios que alojamos y, aunque hemos solucionado el problema con respecto a los ataques de inyección de encabezado, todavía tenemos que controlar los ataques de carga.

Estoy tratando de configurar una serie de scripts de carga tipo plug-and-play para usar de forma interna que un diseñador pueda copiar en la estructura de su sitio, modificar algunas variables y tener listo para usar cargar formulario en su sitio. Estamos tratando de limitar nuestra exposición tanto como sea posible (ya hemos cerrado los comandos fopen y shell).

He buscado en el sitio durante la última hora y he encontrado muchas respuestas diferentes relacionadas con métodos específicos que se basan en fuentes externas. ¿Cuál cree que es la mejor solución de solo script que es lo suficientemente específica como para utilizarla como un método confiable de protección? Además, me gustaría mantener el lenguaje limitado a PHP o pseudocódigo si es posible.

Editar: encontré mi respuesta (publicada a continuación) y, aunque hace uso del comando de shell exec (), si bloquea los archivos de script para que no se carguen (lo que hace esta solución muy bien), no tendrás problemas.

¿Fue útil?

Solución

La mejor solución, IMHO, es colocar el directorio que contiene los archivos cargados fuera de " web " entorno y usar un script para hacerlos descargables. De esta manera, incluso si alguien carga un script, no se puede ejecutar llamándolo desde el navegador y no tiene que verificar el tipo de archivo cargado.

Otros consejos

  1. Permitir que solo los usuarios autorizados carguen un archivo. También puedes agregar un captcha para impedir los robots primitivos.

  2. En primer lugar, establezca MAX_FILE_SIZE en su formulario de carga , y establezca tamaño máximo de y < code> count en el servidor también.

    ini_set('post_max_size', '40M'); //or bigger by multiple files
    ini_set('upload_max_filesize', '40M');
    ini_set('max_file_uploads', 10);
    

    Compruebe el tamaño por los archivos cargados:

    if ($fileInput['size'] > $sizeLimit)
        ; //handle size error here
    
  3. Debería usar $ _FILES y move_uploaded_file () para colocar sus archivos cargados en el directorio correcto, o si desea procesarlos, verifique con is_uploaded_file ( ) . (Estas funciones existen para evitar inyecciones de nombre de archivo causadas por register_globals .)

    $uploadStoragePath = '/file_storage';
    $fileInput = 
    1. Permitir que solo los usuarios autorizados carguen un archivo. También puedes agregar un captcha para impedir los robots primitivos.

    2. En primer lugar, establezca MAX_FILE_SIZE en su formulario de carga , y establezca tamaño máximo de y < code> count en el servidor también.

      ini_set('post_max_size', '40M'); //or bigger by multiple files
      ini_set('upload_max_filesize', '40M');
      ini_set('max_file_uploads', 10);
      

      Compruebe el tamaño por los archivos cargados:

      if ($fileInput['size'] > $sizeLimit)
          ; //handle size error here
      
    3. Debería usar $ _FILES y move_uploaded_file () para colocar sus archivos cargados en el directorio correcto, o si desea procesarlos, verifique con is_uploaded_file ( ) . (Estas funciones existen para evitar inyecciones de nombre de archivo causadas por register_globals .)

          SetHandler none
          SetHandler default-handler
          Options -ExecCGI
          php_flag engine off
      

      Siempre genere un ID aleatorio en lugar de usar el nombre del archivo original .

    4. Cree un nuevo subdomain por ejemplo http://static.example.com o al menos un nuevo directorio fuera de public_html , para los archivos cargados. Este subdominio o el directorio no deben ejecutar ningún archivo . Establézcalo en la configuración del servidor, o establezca en un < strong> .htaccess por el directorio.

          $noExecMode = 0644;
          chmod($uploadedFile, $noExecMode);
      

      Configúralo con chmod () también.

      $userContent = '../uploads/malicious.jpg';
      include('includes/'.$userContent);
      

      Use chmod () en los archivos recién cargados y configúrelo en el directorio.

    5. Debes verificar el tipo mime enviado por el hacker. Debería crear una lista blanca de tipos mime permitidos. Permitir solo imágenes si no es necesario ningún otro formato. Cualquier otro formato es una amenaza de seguridad. Imágenes también, pero al menos tenemos herramientas para manejarlas ...
      El contenido dañado , por ejemplo: HTML en un archivo de imagen puede causar XSS en los navegadores con sniffing de contenido vulnerabilidad . Cuando el contenido dañado es un código PHP , entonces se puede combinar con una vulnerabilidad eval injection .

      Strict-Transport-Security: max-age={your-max-age}
      X-Content-Type-Options: nosniff
      X-Frame-Options: deny
      X-XSS-Protection: 1; mode=block
      Content-Security-Policy: {your-security-policy}
      

      Intente evitar esto, por ejemplo, use un class autoloader en lugar de incluir archivos php manualmente ...
      Al manejar la inyección de javascript , primero tiene que desactivar xss y detectar contenido en los navegadores . Los problemas de oler el contenido son típicos de los msie más antiguos, creo que los otros navegadores los filtran bastante bien. De todos modos puedes prevenir estos problemas con un montón de encabezados. (No es totalmente compatible con todos los navegadores, pero eso es lo mejor que puede hacer en el lado del cliente).

      try {
          $uploadedImage = new Imagick($uploadedFile);
          $attributes = $uploadedImage->identifyImage();
          $format = $image->getImageFormat();
          var_dump($attributes, $format);
      } catch (ImagickException $exception) {
          //handle damaged or corrupted images
      }
      

      Puede verificar si un archivo está corrompido con Imagick identifique , pero eso no significa una protección completa.

      X-Download-Options: noopen
      Content-Disposition: attachment; filename=untrustedfile.html
      

      Si quieres servir a otros tipos mime , siempre debes forzar la descarga por ellos, nunca incluir en páginas web, a menos que realmente sepa lo que está haciendo ...

      <*>
    6. Es posible tener archivos de imagen válidos con un código dentro de ellos, por ejemplo, en los datos de exif . Por lo tanto, debe eliminar exif de las imágenes si su contenido no es importante para usted. Puede hacer eso con Imagick o GD , pero ambos requieren el reenvasado del archivo. Puede encontrar un exiftool como alternativa. Creo que la forma más sencilla de borrar exif , es cargar imágenes con GD y guárdalos como PNG con la mejor calidad . Por lo tanto, las imágenes no perderán calidad, y la etiqueta exif se eliminará, ya que GD no puede manejarlo. Haz esto con las imágenes subidas como PNG también ...
      Si desea extraer los datos de exif , nunca use preg_replace () si el patrón o replacement proviene de usuario, ya que eso llevará a una inyección inyectable ... Use preg_replace_callback () en lugar de eval regex flag , si es necesario. (Error común en los códigos de pegado de copia). Los datos de Exif pueden ser un problema si su sitio tiene una vulnerabilidad de eval injection , por ejemplo, si usa include ($ userInput) en alguna parte.

    7. Nunca use include () , require () por los archivos cargados , sírvalos como estáticos o use file_get_contents () o readfile () , o cualquier otra función de lectura de archivos, si desea controlar el acceso.
      Rara vez está disponible, pero creo que el mejor enfoque para usar los encabezados X-Sendfile: {filename} con los sendfile apache module . Por los encabezados, nunca utilice la entrada del usuario sin validación o desinfección, ya que esto llevará a inyección de encabezado HTTP .
      Si no necesita control de acceso (significa: solo los usuarios autorizados pueden ver los archivos cargados), entonces sirva los archivos con su servidor web. Es mucho más rápido ...

    8. Use un antivir para verificar los archivos cargados, si tiene uno.

    9. Siempre use una protección combinada , no solo un enfoque único. Será más difícil romper tus defensas ...

    FILES['image']; if ($fileInput['error'] != UPLOAD_ERR_OK) ; //handle upload error here, see http://php.net/manual/en/features.file-upload.errors.php //size check here $temporaryName = $fileInput['tmp_name']; $extension = pathinfo($fileInput['name'], PATHINFO_EXTENSION); //mime check, chmod, etc. here $name = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); //true random id move_uploaded_file($temporaryName, $uploadStoragePath.'/'.$name.'.'.$extension);

    Siempre genere un ID aleatorio en lugar de usar el nombre del archivo original .

  4. Cree un nuevo subdomain por ejemplo http://static.example.com o al menos un nuevo directorio fuera de public_html , para los archivos cargados. Este subdominio o el directorio no deben ejecutar ningún archivo . Establézcalo en la configuración del servidor, o establezca en un < strong> .htaccess por el directorio.

    <*>

    Configúralo con chmod () también.

    <*>

    Use chmod () en los archivos recién cargados y configúrelo en el directorio.

  5. Debes verificar el tipo mime enviado por el hacker. Debería crear una lista blanca de tipos mime permitidos. Permitir solo imágenes si no es necesario ningún otro formato. Cualquier otro formato es una amenaza de seguridad. Imágenes también, pero al menos tenemos herramientas para manejarlas ...
    El contenido dañado , por ejemplo: HTML en un archivo de imagen puede causar XSS en los navegadores con sniffing de contenido vulnerabilidad . Cuando el contenido dañado es un código PHP , entonces se puede combinar con una vulnerabilidad eval injection .

    <*>

    Intente evitar esto, por ejemplo, use un class autoloader en lugar de incluir archivos php manualmente ...
    Al manejar la inyección de javascript , primero tiene que desactivar xss y detectar contenido en los navegadores . Los problemas de oler el contenido son típicos de los msie más antiguos, creo que los otros navegadores los filtran bastante bien. De todos modos puedes prevenir estos problemas con un montón de encabezados. (No es totalmente compatible con todos los navegadores, pero eso es lo mejor que puede hacer en el lado del cliente).

    <*>

    Puede verificar si un archivo está corrompido con Imagick identifique , pero eso no significa una protección completa.

    <*>

    Si quieres servir a otros tipos mime , siempre debes forzar la descarga por ellos, nunca incluir en páginas web, a menos que realmente sepa lo que está haciendo ...

    <*>
  6. Es posible tener archivos de imagen válidos con un código dentro de ellos, por ejemplo, en los datos de exif . Por lo tanto, debe eliminar exif de las imágenes si su contenido no es importante para usted. Puede hacer eso con Imagick o GD , pero ambos requieren el reenvasado del archivo. Puede encontrar un exiftool como alternativa. Creo que la forma más sencilla de borrar exif , es cargar imágenes con GD y guárdalos como PNG con la mejor calidad . Por lo tanto, las imágenes no perderán calidad, y la etiqueta exif se eliminará, ya que GD no puede manejarlo. Haz esto con las imágenes subidas como PNG también ...
    Si desea extraer los datos de exif , nunca use preg_replace () si el patrón o replacement proviene de usuario, ya que eso llevará a una inyección inyectable ... Use preg_replace_callback () en lugar de eval regex flag , si es necesario. (Error común en los códigos de pegado de copia). Los datos de Exif pueden ser un problema si su sitio tiene una vulnerabilidad de eval injection , por ejemplo, si usa include ($ userInput) en alguna parte.

  7. Nunca use include () , require () por los archivos cargados , sírvalos como estáticos o use file_get_contents () o readfile () , o cualquier otra función de lectura de archivos, si desea controlar el acceso.
    Rara vez está disponible, pero creo que el mejor enfoque para usar los encabezados X-Sendfile: {filename} con los sendfile apache module . Por los encabezados, nunca utilice la entrada del usuario sin validación o desinfección, ya que esto llevará a inyección de encabezado HTTP .
    Si no necesita control de acceso (significa: solo los usuarios autorizados pueden ver los archivos cargados), entonces sirva los archivos con su servidor web. Es mucho más rápido ...

  8. Use un antivir para verificar los archivos cargados, si tiene uno.

  9. Siempre use una protección combinada , no solo un enfoque único. Será más difícil romper tus defensas ...

Use y configure Hardened-PHP para crear una secuencia de comandos simple usando move_uploaded_file y $ _ FILES superglobal . Cuanto más sencillo sea el script, más seguro será (al menos, tan seguro como la propia versión de PHP)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top