tmpnam advertencia diciendo que es peligroso

5 minutos de lectura

Avatar de usuario de Cenoc
cenoc

Recibo esta advertencia que dice que tmpnam es peligroso, pero preferiría usarlo, ya que se puede usar tal como está en Windows y Linux. Me preguntaba por qué se consideraría peligroso (supongo que es por el potencial de uso indebido en lugar de que en realidad no funcione correctamente).

  • ¿Podrías agregar algo de contexto? ¿Quién dice que es peligroso?

    – nmichaels

    21 de julio de 2010 a las 13:46

  • Es tmpname un nombre de variable, un nombre de archivo, un nombre de archivo fuente o algo completamente diferente? No todos tenemos habilidades psíquicas.

    – sbi

    21 de julio de 2010 a las 13:50

  • @sbi: tmpnam es una función de biblioteca estándar de C.

    –Mike Seymour

    21 de julio de 2010 a las 14:13

  • @Nathon En realidad estaba hablando tanto de gcc como de msvc, solo me preguntaba cuál es la razón para decir que es peligroso. @sbi Supongo que debería haber mencionado que era una función de biblioteca estándar.

    – cenoc

    21 de julio de 2010 a las 14:18

  • Si un hacker tiene su código. Puede adjuntar un depurador y pausar el programa justo después de que su código llame a tmpnam() pero antes de que abra el archivo. Luego, el atacante modificará el sistema de archivos para que tenga acceso al archivo y luego deje que su código continúe. El atacante ahora tiene acceso completo a sus datos tmp. Alternativamente, si usa tmpfile(), no abre esta vulnerabilidad en el código, ya que es mucho más difícil para el atacante detener el código mientras se encuentra en la parte privilegiada del sistema operativo.

    – Martín York

    21 de julio de 2010 a las 16:26

Avatar de usuario de Scharron
Scharron

De la página de manual de tmpnam:

La función tmpnam() genera una cadena diferente cada vez que se llama, hasta TMP_MAX veces. Si se llama más de TMP_MAX veces, el comportamiento está definido por la implementación.

Aunque tmpnam() genera nombres que son difíciles de adivinar, es posible que entre el momento en que tmpnam() devuelve un nombre de ruta y el momento en que el programa lo abre, otro programa podría crear ese nombre de ruta usando open(2), o créalo como un enlace simbólico. Esto puede conducir a agujeros de seguridad. Para evitar tales posibilidades, use el indicador open(2) O_EXCL para abrir el nombre de la ruta. O mejor aún, use mkstemp(3) o tmpfile(3).

Mktemp realmente crea el archivo, por lo que está seguro de que funciona, mientras que tmpnam devuelve un nombre, posiblemente ya existente.

  • Usando mktemp es Unix solo para Windows que necesita tmpnam_s y _wtmpnam_s. Por lo tanto, una versión independiente de la plataforma no es tan fácil.

    – usr1234567

    23 de abril de 2015 a las 7:56

Si desea utilizar el mismo símbolo en varias plataformas, utilice una macro para definir TMPNAM. Siempre que elija funciones más seguras con la misma interfaz, podrá usarlas en ambos. Tiene compilación condicional en algún lugar de su código de todos modos, ¿verdad?

si habla sobre la advertencia del compilador de MSVC:

 These functions are deprecated because more secure versions are available;
 see tmpnam_s, _wtmpnam_s.

(http://msdn.microsoft.com/de-de/library/hs3e7355(VS.80).aspx)

de lo contrario, simplemente lea lo que dicen las páginas de manual sobre los inconvenientes de esta función. se trata principalmente de un segundo proceso que crea exactamente el mismo nombre de archivo que acaba de hacer su proceso.

avatar de usuario de janneb
janneb

Desde la página de manual de tmpnam(3):

Aunque tmpnam() genera nombres que son difíciles de adivinar, es posible que entre el momento en que tmpnam() devuelve un nombre de ruta y el momento en que el programa lo abre, otro programa podría crear ese nombre de ruta usando open(2) , o créelo como un enlace simbólico. Esto puede conducir a agujeros de seguridad. Para evitar tales posibilidades, use el indicador open(2) O_EXCL para abrir el nombre de la ruta. O mejor aún, use mkstemp(3) o tmpfile(3).

La función es peligrosa, porque usted es responsable de asignar un búfer que sea lo suficientemente grande para manejar la cadena que tmpnam() va a escribir en ese búfer. Si asigna un búfer que es demasiado pequeño, tmpnam() no tiene forma de saberlo, y desbordará el búfer (causando estragos). tmpnam_s() (versión segura de MS) requiere que pase la longitud del búfer, por lo que tmpnam_s saber cuándo parar.

  • Hay una constante de preprocesador L_tmpnam que especifica la longitud máxima que escribirá la implementación (o en un programa de un solo subproceso, puede usar un puntero NULL en cuyo caso usará un búfer estático). Por lo tanto, es un problema fácilmente evitable. La parte peligrosa proviene de la posible condición de carrera entre la creación del nombre del archivo y, posteriormente, la creación del propio archivo.

    – janneb

    21 de julio de 2010 a las 17:08


  • La mayoría de los agujeros de seguridad son fáciles de evitar. (Su respuesta cita una manera fácil de evitar el problema que describe). El problema que describo es más probable que ocurrir si no sigues las reglas. (también es el problema solucionado por tmpnam_s(), por lo que es claramente el problema en el que estaban pensando)

    – James Curran

    21 de julio de 2010 a las 17:27

  • Hay una constante de preprocesador L_tmpnam que especifica la longitud máxima que escribirá la implementación (o en un programa de un solo subproceso, puede usar un puntero NULL en cuyo caso usará un búfer estático). Por lo tanto, es un problema fácilmente evitable. La parte peligrosa proviene de la posible condición de carrera entre la creación del nombre del archivo y, posteriormente, la creación del propio archivo.

    – janneb

    21 de julio de 2010 a las 17:08


  • La mayoría de los agujeros de seguridad son fáciles de evitar. (Su respuesta cita una manera fácil de evitar el problema que describe). El problema que describo es más probable que ocurrir si no sigues las reglas. (también es el problema solucionado por tmpnam_s(), por lo que es claramente el problema en el que estaban pensando)

    – James Curran

    21 de julio de 2010 a las 17:27

¿Ha sido útil esta solución?