¿Hay alguna ventaja en crear un archivo temporal de una manera más cuidadosa?
Los archivos temporales generalmente se crean en el directorio temporal (como /tmp
) donde todos los demás usuarios y procesos tienen acceso de lectura y escritura (cualquier otro script puede crear los nuevos archivos allí). Por lo tanto, la secuencia de comandos debe tener cuidado al crear los archivos, como usarlos con los permisos correctos (por ejemplo, solo lectura para el propietario, consulte:help umask
) y el nombre del archivo no debe ser fácil de adivinar (idealmente al azar). De lo contrario, si los nombres de archivo no son únicos, puede crear un conflicto con el mismo script ejecutado varias veces (por ejemplo, condición de carrera) o algún atacante podría secuestrar información confidencial (por ejemplo, cuando los permisos son demasiado abiertos y el nombre de archivo es fácil de adivinar) o crear /reemplazar el archivo con su propia versión del código (como reemplazar los comandos o las consultas SQL según lo que se almacene).
Podría utilizar el siguiente enfoque para crear el directorio temporal:
TMPDIR=".${0##*/}-$$" && mkdir -v "$TMPDIR"
o archivo temporal:
TMPFILE=".${0##*/}-$$" && touch "$TMPFILE"
Sin embargo, sigue siendo predecible y no se considera seguro.
Según man mktemp
, podemos leer:
Tradicionalmente, muchos scripts de shell toman el nombre del programa con el pid como sufijo y lo usan como un nombre de archivo temporal. Este tipo de esquema de nombres es predecible y la condición de carrera que crea es fácil de ganar para un atacante.
Entonces, para estar seguro, se recomienda usar mktemp
comando para crear un archivo o directorio temporal único (-d
).
El mktemp(1)
La página de manual lo explica bastante bien:
Tradicionalmente, muchos scripts de shell toman el nombre del programa con el pid como sufijo y lo usan como un nombre de archivo temporal. Este tipo de esquema de nombres es predecible y la condición de carrera que crea es fácil de ganar para un atacante. Un enfoque más seguro, aunque todavía inferior, es crear un directorio temporal usando el mismo esquema de nombres. Si bien esto permite garantizar que un archivo temporal no será alterado, todavía permite un simple ataque de denegación de servicio. Por estas razones, se sugiere usar mktemp en su lugar.
En un script, invoco mktemp algo como
mydir=$(mktemp -d "${TMPDIR:-/tmp/}$(basename $0).XXXXXXXXXXXX")
que crea un directorio temporal en el que puedo trabajar y en el que puedo nombrar de forma segura los archivos reales algo legible y útil.
mktemp
no es estándar, pero existe en muchas plataformas. Las "X" generalmente se convertirán en algo aleatorio, y más probablemente serán más aleatorios; sin embargo, algunos sistemas (busybox ash, por ejemplo) limitan esta aleatoriedad más significativamente que otros
Por cierto, la creación segura de archivos temporales es importante para algo más que para la creación de scripts de shell. Es por eso que Python tiene Tempfile, Perl tiene File::Temp, Ruby tiene Tempfile, etc...
Es posible que desee ver mktemp
La utilidad mktemp toma la plantilla de nombre de archivo dada y sobrescribe una parte de ella para crear un nombre de archivo único. La plantilla puede ser cualquier nombre de archivo con un número de 'X' adjunto, por ejemplo/tmp/tfile.XXXXXXXXXX. Las 'X' finales se reemplazan con una combinación del número de proceso actual y letras aleatorias.
Para más detalles:man mktemp
Sí, usa mktemp.
Creará un archivo temporal dentro de una carpeta diseñada para almacenar archivos temporales y le garantizará un nombre único. Muestra el nombre de ese archivo:
> mktemp
/tmp/tmp.xx4mM3ePQY
>